|
|
|
|
|
|
|
$Date: 2002/06/17 11:55:17 $
|
Compassion -- that's the one things no machine ever had. Maybe it's
the one thing that keeps men ahead of them.
|
|
--McCoy, "The Ultimate Computer", stardate 4731.3 |
|
Abstract
This chapter provides an technical overview about the developed iChilli™ system components - as applicable. Basically those system components are devided into a server subsystem and a client subsystem (PersonalChilli). Because the main focuss of this diploma thesis was to port an already existing EJB container to the Java™ environment of mobile devices, the PersonalChilli section will certainly be more detailed. Additionally the section Application Deployment will give a perspective about an upcoming technology, that will simplify deployment of mobile applications.
The iChilli™ Server Infrastructure
As illustrated in section The iChilli Vision, the iChilli™ server infrastructure needs the ability to run several server processes at once. Below is a list of server processes that are needed to be supported.
-
Servlet Container (provided by Tomcat)
-
JSP Container (provided by Tomcat)
-
EJB Container (provided by OpenEJB)
-
JMS Server (provided by JORAM)
-
SOAP/XML-RPC Server (provided by Axis)
-
UDDI Registry Server (not implemented right now)
-
J2EE Provisioning Server (currently provided by using the Sun reference implementation (RI))
Because developing such a server runtime environment from scratch would be time consuming and not in the scope of this diploma thesis, it was necessary to choose an already existing server and component model framework that supports a faster development of all the different servers.
The Apache Avalon project provides a component model for Java™ server application and several so-called containers that are providing an infrastructure for building custom servers (for example, a FTP server). The Avalon component framework provides components such as a Configuration API that allows to configure servers based on the configuration entries contained within a XML file. The Avalon container that was choosen to run the above mentioned iChilli™ servers, is called Phoenix. More information about Avalon can be found at the Avalon web site and within an Avalon article which appeared in the german JavaMagazin [[haischt, 2001]].
The below figure describes the Avalon components just mentioned.
Explanation
|
The Avalon component framework that provides basic components which are needed to create a new TCP/IP based server.
|
|
The Avalon LogKit - a logging framework.
|
|
The Avalon Phoenix server which provides a runtime environment for several different TCP/IP based server.
|
|
The Avalon Cornerstone scheduler block, which is a Cron[8] like service that allows to execute tasks on a regular basis.
|
|
The Avalon Cornerstone socket manager, which provides a way to create and manage server sockets easily.
|
|
Some demo blocks.
|
As shown in the previous figure, services and servers that are offering some kind of a service (for example, an EJB service), need to be wrapped into a so-called Block if those services are supposed to be run inside the Avalon Phoenix container. So lets imagine having a basic mail server that should be wrapped as an Avalon Phoenix block - The following figure illustrates such an email server block, including several protocol handlers that are handling different internet protocols.
Every Avalon Phoenix block will be packaged into a so-called SAR[9]. The SAR package includes a deployment descriptor and some configuration files, which causes each block to be configured, initialized and started while starting the Avalon Phoenix system. If the particular block or service is setup accordingly, it will be started without the requirement of any user interactions.
The iChilli™ Server Decomposition.
Because of the above mentioned Block/Service paradigm, it was necessary to wrap any server that should be run within the iChilli™ system into an Avalon Phoenix compliant block. After having evaluated several different design approach of how to start all the different servers, the final result contains a single iChilli™ server that will be initialized and started by the Avalon Phoenix system. The iChilli™ server in turn is responsible to initialize and start all the different servers listed at the beginning of this section. To initialize, start and manage a server (for example, a Servlet
Conatiner or an OpenEJB Server as shown below) a so-called IchilliServerFactory is required, which is implemented using a singleton, a design pattern that ensures that there exists only one instance of that factory during runtime. Additionally each server can be managed using JMX[10], a functionality provided by the Avalon Phoenix system.
Some iChilli™ server are required to support Hot Deployment of new application components. The iChilli™ block that wrapps the OpenEJB server, needs to be able to recognize if someone just copied a new Java™ Enterprise Bean into OpenEJB's bean directory while the EJB server is running. The iChilli™ EJB block needs such capabilities, because it is unpleasant to require the user to restart the whole iChilli™ server system after having deployed a new Java™ Enterprise Bean. So Hot Deployment
basicly means to detect just deployed components while a server is running, to be able to integrate those components into an already running system.
Supporting Hot Deployment for all the different J2EE components requires in turn a hirarchical Classloader structure, because Servlets for example have to be loaded by a different Classloader as Java™ Enterprise Beans. This requirement is the reason why each iChilli™ server gets its own unique ClassLoader structure. How to configure a Classloader hirarchy will be described later on. The iChilli™ Classloader system is illustrated in
the following example.
Basicly composing a Classloader structure is somehow similar to creating different iChilli™ server, because a IchilliClassLoaderFactory is responsible for instantiating all the different Classloader to put them finally into the appropriate hirarchy. A IchilliClassLoader implements two interfaces:
-
IchilliChangeable because the Classloader is attached to a directory which contains components that are meant to be hot deployed, which causes the contents of the Classloader to be changed after the occurence of a Hot Deployment action.
-
IchilliNameable because every Classloader got a unique name by which it can be identified.
Every iChilli™ server that wants to recieve Hot Deployment notifications needs to implement the interface IchilliClassLoaderListner.
The below example of an iChilli™ Avalon Phoenix configuration file demonstrates how a Classloader structure will be defined.
1| <config>
2| <ichilli-server>
3| <!-- Generic Configuration Parameters -->
4|
5| <!-- Server Declarations -->
6| <servers>
7| <server>
8| <name>OpenEJB</name>
9| </server>
10| <server>
11| ´<name>JORAM</name>
12| </server>
13| <server>
14| <name>Tomcat</name>
15| </server>
16| </servers>
17|
18| <!-- Server Specific Configuration Parameters -->
19| <openejb>
20| <properties>
21| <openejb.home>${block.context}/openejb</openejb.home>
22| </properties>
23| <classloaders>
24| <classloader>
25| <name>openejb</name>
26| <entry>${openejb.home}/lib/*.jar</entry>
27| <monitored>false</monitored>
28| </classloader>
29| <classloader>
30| <name>openejb.beans</name>
31| <entry>${openejb.home}/beans/*.jar</entry>
32| <monitored>true</monitored>
33| </classloader>
34| </classloaders>
35| </openejb>
36| </ichilli-server>
37| </config>
38|
Explanation
|
Declares several servers that should be configured.
|
|
The configuration entry for the OpenEJB server.
|
|
The Classloaders that will be attached to the OpenEJB server.
|
|
A Classloader named openejb which loads every jar contained within ${openejb.home}/lib/.
|
|
A Classloader named openejb.beans which will load every jar contained within ${openejb.home}/beans/.
|
|
This flag indicates that this directory has to be monitored for the event of file changes. This behaviour will basicly trigger an changed event which will be then send to an IchilliClassLoaderListener.
|
The above figure finally recaptualizes the previously described iChilli™ server and Classloader infrastructure. Basicly Avalon Phoenix configures and initializes the IchilliService, which in turn configures and starts every server definded in the previously described configuration file using the IchilliClassLoaderFactory and IchilliServerFactory.
According to the section The iChilli Server Infrastructure at the begining of this chapter, the following servers were actually implemented at a very basic level.
-
An EJB server
-
A JMS server
The following services are supposed to be additionally services according to the iChilli™ core services (Servlets, JSP, EJB, JMS, SOAP/XML-RPC).
The PersonalChilli™ Concept
This section illustrates a revised system architecture of the PersonalChilli mobile EJB container. The revised system architecture directly results after having defined specific system requirements in chapter - Specific Requirements additionally the revised system architecture is influenced by Braun's diploma thesis [[braun, 2002]]. Braun describes a JavaSpaces™ compliant micro space for mobile devices. Basicly this revised system architecture has become necessary because that mobile client not only needs to persist data, the client also needs to replicate data[11] and synchronize changes resulting from an offline operation. The figure
below illustrates the just discussed revised system architecture.
Explanation
|
PersonalChilli - The mobile EJB container as described of section The iChilli Vision.
|
|
The Lime Java™ middleware, which provides object distribution.
|
|
ChilliBridge - Provides data persistency[12].
|
|
ChilliBroker - A combination of a Transaction Manager & Transaction Coordinator. This architectural element is currently implemented using dtF/AF.
|
Basicly PersonalChilli doesn't provide a GUI layer, because it is a server system and no user application. Allthough under special circumstances it was necessary to start/stop the mobile EJB container from within a graphical user interface. As described in section Mobile Operating Systems Palm OS™ for example, isn't able to support background or even server processes that will be started during system startup (boot) time. Same applies to MIDP compliant devices. As a result it isn't possible to have an EJB container that runs in the background and additionally start a graphical client application that accesses the EJB container.
That finally means that an EJB container that runs on Palm OS™ has to be started by some kind of a library call from within an already running application. Allthough suspending or even shutting down the application also means terminating the EJB container that was just started with that specific application. This requires the graphical application to notify the EJB container before getting suspended or shut down. This behaviour finally gives the server a chance to finish pending transactions and persist changed data.
The subject of implementing an user interface layer that supports J2ME devices was completly discarded, hence it isn't within the scope of this thesis. Thus the objective was to use an allready existing GUI toolkits for mobile devices. While searching for situable GUI toolkits the following toolkits were taken into closer considerations.
-
AWT - Abstract Window Toolkit (contained within every java development kit since jdk1.x).
-
The dtF/AF generative GUI framework, which provides dynamically generated user interfaces.
-
Thinlets, which is a project that provides new GUI components independed fom Swing or AWT. According to the product description thinlets are supposed to work on MIDP - as a result of evaluating this technology it could be clearified that thinlets are running within a MIDP emulating environment but not on a real MIDP device (e.g. a cellular phone).
-
LwVCL, which is a completly new Visual Component Library (VCL), independend from already existing technologies such as Swing or AWT. The VCL library supports PersonalJava/Personal Profile runtime environments.
Finally for the sake of simplicity, AWT were choosen because of beeing already familiar with that GUI toolkit.
The term application layer refers to a system component that is able to execute some kind of application logic. In the scope of this diploma thesis this will be in fact an EJB container. Thus business logic will be provided by Java™ Enterprise Beans. At a very early stage the people involved with this diploma thesis had a consensus that programming a new mobile EJB container just out of the void, would be very time consuming. As a result it was clear that the only alternativ would be to port an already existing EJB container to PersonalJava and possibly MIDP, respectively. After having evaluated several EJB containers it was finally possible to elect one EJB container for beeing a porting candidate. The final decission was to use OpenEJB because of the performance results found in section Mobile Operating Systems, the fact that OpenEJB can be run in embedded mode (will be explained later) and the fact that the author of this diploma thesis is a member of the OpenEJB project. Thus he knows that container very well.
As previously mentioned OpenEJB can be run in embedded mode. From the view of a Java™ developer this means that the OpenEJB runtime system can be instantiated just like a call to any other Java™ library. This in turn means that OpenEJB can be embedded into an user's mobile application. Embedding OpenEJB into an user's mobile application would solve for example, the previously mentioned problem that applications on Palm OS™ can't be run as a server application. The following figure illustrates the two contrary runtime modes of OpenEJB.
Allthough while beeing embeddable, OpenEJB won't eliminate the fact that J2ME profiles running on top of CLDC are missing most Java™ APIs needed to run an EJB container. Section The MIDP Feature Set Generative Transformation System illustrates an alternative approach of how Java™ Enterprise Beans could be brought to such devices.
Mode one at the left side is called IntraVM Mode, which basicly refers to the fact, that OpenEJB is running in the same Java™ virtual machine as the user's application does. EJB objects will be accessed using JNDI lookups during IntraVM mode.
Mode two at the right side is called Remote Server Mode and supplies a real distributed environment, because the EJB client does not need necessarily to run on the same machine as the remote server does. EJB objects in this mode will be accessed using some kind of RPC calls[14].
To leverage the embeddable approach of OpenEJB a so called admin client was created, which fulfills the need of having a J2ME application that starts the OpenEJB runtime environment. Basicly this admin client is able to start an IntraVM server, or if necessary a Remote Server that resides at the same machine as the admin application. While developing and testing the just described application the Sharp Zaurus Linux™ PocketPC served as a mobile hosting environment.
The following figure illustrates how the admin application starts a Remote Server.
Basicly the above class diagram shows the composition of a AWT frame (e.g. an application window), which contains some menu items like start, stop, restart. Those menu items are causing the PersonalChilli Daemon to be started, stopped or restarted. The PersonalChilli Daemon in turn initializes the OpenEJB system by staticaly calling org.openejb.OpenEJB.init() and creates a server socket to recieve incoming OpenEJB protocol messages.
The more elegant way to use OpenEJB on a mobile device, would be in embedded mode. Running OpenEJB in embedded mode has the positive side-effect that no server needs to be instantiated that creates a server socket and other unnecessary stuff. The below code snippet illustrates a replacement for the PersonalChilliAdmin.startPersonalChilli method, which will start the OpenEJB system in embedded mode.
1| import java.util.Properties;
2| import javax.naming.Context;
3| import javax.naming.InitialContext;
4| import javax.rmi.PortableRemoteObject;
5| import FooHome;
6|
7| public class MyEjbApplication
8| {
9| public static void main( String args[])
10| {
11| try
12| {
13| Properties properties = new Properties();
14|
15| properties.put(
16| Context.INITIAL_CONTEXT_FACTORY,
17| "org.openejb.client.LocalInitialContextFactory");
18|
19| InitialContext ctx = new InitialContext(properties);
20|
21| Object obj = ctx.lookup("my/bean/Foo");
22|
23| FooHome ejbHome = (FooHome)
24| PortableRemoteObject.narrow(obj,
25| FooHome.class);
26| }
27| catch (Exception e)
28| {
29| e.printStackTRace();
30| }
31| }
32| }
33|
Explanation
|
Causes a instance of org.openejb.client.LocalInitialContextFactory to be created.
|
|
Tries to lookup a specific Enterprise Bean.
|
|
Creates a proxy instance of that EJB.
|
To illustrate what basiclly happens it would be necessary to introduce the below sequence diagram.
The above sequence diagram shows that while the client requests an initial JNDI context, the OpenEJB context factory returns such a context after having initialized the OpenEJB system.
While developing an EJB container for a J2ME environment, several elements turned out to be siginificantly challenging. This sections describes the most significant challenges and explains why they turned out to be challenging.
Because the initial point of developing a mobile EJB container was to use an already existing EJB container that runs on top of some J2SE implementation, it was obvious that while back-porting the container to jdk1.1.8 (e.g. PersonalJava) there will emerge various problems because of missing or inadequate Java™ API's that did not exist in jdk1.1.8. Because this problem was a well known problem from the time starting to port the container, it was considered to be quite time consuming but managable.
Actually while back-porting a server system to jdk1.1.8 to finally use it on a mobile devices, it was required to decide which OpenEJB system component could be stripped of in favour of a leaner mobile container. Because the decission of stripping-of some system components isn't a random activity, in-deep knowledge was required to savely reduce the complexity of the OpenEJB system. This requirement finally resulted in an analyzation phase of the OpenEJB system.
While analyzing the OpenEJB system, it became apparently that the current OpenEJB system is using so-called dynamic Proxies[16], which were initially introduced in J2SE version 1.3. Basicly a Proxy is a design pattern which prevents users from directly accesing Java™ object (see [[gamma, helm, johnson and vlissides, 2000]]). The Proxy object rather allows the user to access objects through some kind of a
barrier. Proxies are used within the OpenEJB system to access EJBs via a Proxy. Actually in early days (before J2SE version 1.3) those EJB proxies were not created during runtime but rather by some Parser Generator which has to be executed during development time. This Parser Generator could be compared to the RMI rmic tool which generates RMI stubs & skeletons out of plain Java™ files.
So having such a Parser Generator for jdk1.1.8 which would have generated all the EJB Proxy object staticaly, could have solved the problem but would have been very time consuming.
A second problem that occured while analyzing the OpenEJB system, was the fact that OpenEJB is using the Castor JDO persistence framework to provide both, CMP and BMP persistency. Because Castor is a fully-blown Java™ API for J2SE systems only, it was necessary to consider to completly discard the current CMP and BMP implementations of OpenEJB. Actually at this point at time it became clear for the first time that finishing the mobile EJB container would consume more time than initially expected.
A second problem that comes along with Castor is the fact that the OpenEJB configuration system heavily relies on Castor, which provides some sort of XML-To-Java data binding. The configuration system is needed to read all the configuration entries from the configuration files to finally asemble the whole OpenEJB container system accordingly. Discarding Castor would also mean the requirement of implement a new configuration system and an assembler that assembles all the various OpenEJB
containers.
Finally the persistence layer needs to provide some kind of object distribution, because objects residing on the server are required to be replicated to a mobile client. This is a feature that is unique to iChilli™ and is completly missing within the OpenEJB system.
The Mobile Persistence Layer
As mentioned earlier, PersonalChilli runs on top of a so-called persistence layer, which is required to persist Java™ object to some kind of media, to be able to preserve their state for a later use. From a application server point of view, a persistence layer allows the server to be restarted without loosing the state of every object.
While trying to port OpenEJB over to jdk1.1.8 one major problem was that the persistence layer which shipped with OpenEJB (Castor) couldn't be used because it was originally developed for a J2SE environment, thus it was practically impossible to use Castor on a mobile device.
As a first initial step to solve the previously described problem it was necessary to undergo some investigations, whether there is a persistence layer that is jdk1.1.8 compliant and could be used as a replacement for the already existing OpenEJB persistence layer. A simple persistence layer that is able to bind data that is defined in a XML file to Java™ objects during runtime would have been sufficient.
The below table contains possible open source candidates that have been found while searching for object-relational mapping tools, or APIs that are able to bind data contained within a XML file to a Java™ object.
Table 6.1. Persistence Layer Comparison[17]
Finally only the simple dtF/AF data binding tool and the Hibernate OR mapping framework were situable for PersonalJava. Allthough implementing a new BMP/CMP container for the mobile EJB container was discarded because of time constraints.
The Distributed Object Layer
The PersonalChilli distributed object layer provides the ability to operate in a nearly autarkic manner. That means while experiencing a disconnect, the mobile client is still able to execute some application logic. Additionally the distributed object layer provides a replication and sysnchronization facility.
The Linda Tuple Spaces Concept
Linda [[golvin, cooperstein, schaeffer and Scaffidi, 2002]] was initialy introduced at the Yale university in 1985 as a language to coordinate parallel processes. Linda introduces the paradigm of so-called Tuple Spaces which are providing a communication facility for different processes. In general a Tuple Space has to be considered as a black box. To communicate with other processes, a proccess doesn't need to exchange messages, the process rather just creates a data object, a so-called Data Object Tuple, and puts it in the Tuple
Space. Other processes are now able to read that data object from the Tuple Space.
The global paradigm of Linda are Tuple Spaces which have to be considered to be a vector V = (P1, P2, ..., Pn).
The below list illustrates how those Tuple Spaces can be manipulated.
-
out() creates a Data Object Tuple and adds it to the Tuple Space.
-
eval(f(x)) if you consider a Data Object Tuple to be the result of a program, the program could be considered as a vector of processes, which is called a Live Tuple. Actually the result of those vectors are forming the Data Object Tuple. Using the function eval(f(x)) would cause a Live Tuple to be created.
-
in() reads and delets a tuple from a Tuple Space.
-
rd() reads a tuple without deleting it.
Tuple Space operations could be performed using actual and formal parameters. Actual parameters are having an actual value while formal parameters are placeholders for variables of a specific type. The following example would search through the Tuple Space for a tuple containing four elements in('string',?f,?i,'another string'). This tuple will be found if the first element matches the string 'string' and the last element matches the string 'another string'. The both elements in the middle are required to be equivalent to the variables f and i.
Linda Tuple Spaces Implementations
During this thesis it was possible to evaluate the following Tuple Space implementations:
Unfortunatly Sun's JavaSpaces couldn' be used because they are based on the Jini technology which requires a mobile device to support at least RMI. IBM's TSpaces are a programming language indipendend Tuple Space implementation, but unfortunatly TSpaces weren't open source and they don't seem to be really maintained any longer.
Finally there was just only one Tuple Space implementation that supported real mobility in the sense of supporting offline operations. This Tuple Space is the remaining list item - Lime.
How Linda Fits Into the PersonalChilli Concept
While the original Linda system used a global shared Tuple Space, using Linda within a mobile environment wouldn't be sufficient because while remaining ofline, the global Tuple Space won't be accessable which causes the mobile client to interupt the execution of an application.
Basicly Lime provides several Tuple Spaces that are residing on various mobile devices. Those distributed Tuple Spaces are called Transiently Shared Tuple Spaces. Because data in mobile environment has to be considered mobile by itself, such a requirement causes a specific type of software system. Mobile data in this context means that data doesn't necessarily remains allways on the same mobile host. For example data in mobile environments needs to be replicated or synchronized with other hosts. Data mobility in Lime is provided by introducing the agent paradigm. That means every single process is represented by an agent which has the
ability to migrate between different hosts. Agents in turn are having an Interface Tuple Space (ITS) attached to them. This ITS is tightly coupled to the perticular agent, which means it will migrate if the agent starts to migrate. Basicly an ITS supports the opperations in(), rd() and out().
Several agents might form the previously mentioned Transiently Shared Tuple Spaces by concatenating their particular ITS. The picture below illustrates the behaviour of the Lime system.
Basicly while initially working with a Linda system, the Tuple Space paradigm might not be easy to understand, but because Lime comes with several example application it was possible to ensure that Lime supports both connected- and disconnected operations through the help of mobile agents.
While talking with the people at the Washington University it was also possible to get the information that the next version of Lime supports spontanious disconnects, while the current Lime version requires a user to propagate that he want to switch into a disconnect mode (actually getting disconnected is called Disengagement in the Lime context). Thus Lime made a very promissing impression and could be a reason for further investigations in that specific domain.
The MIDP Feature Set Generative Transformation System
While in theory it is possible to port an already existing EJB container to jdk1.1.8, it is completly impossible to undertake the same bold venture for a CLDC based J2ME profile. According to section J2ME Profile Overview MIDP got a completly reduced feature-set compared to jdk1.1.8 and doesn't provide a sufficient infrastructure to run an EJB container (even MIDP version 2.0 wouldn't support a real EJB container).
Because of this constraints a complete different approach has to be taken into consideration. Voelter for example has created an architectural concept for embedded systems which dynamically composes a container system [[voelter, kircher and marquardt, 2001]]. During development time a developer decides which Feature should be used by his application. Uppon that Feature specification a lightweight container system will be composed that only contains those infrastructural elements, that are required to support the Feature set defined by the developer.
The following Feature Set illustrates a system that could be used to dynamically generate a container system.
So for example lets imagine a developer develops an application component that has the specific requirement to be able to communicate over JMS. The resulting container which will be dynamically generated according the features the developer has just selected, will contain a Remote Access component, but only a component that is a concrete implementation of a JMS component. Every other possible Remote Access won't be included in the dynamically generated container.
The previously described approach requires an application to be anylized because it serves as a basis for the container system that has to be generated.
While comming back to the PersonalChilli system, the above approach could be leveraged to generate a custom container system out of existing EJB application. Instead of having some proprietary application components, existing EJBs could be anaylized and transformed into some application logic that fits into the above Feature model. After that the just transformed EJB could be used to generate a custom and leightweight container that runs on a MIDP device.
To illustrate the previous paragraph the following example should explain how the above process should work. A developer for example just developed an Message-Driven Bean that needs to respond to JMS messages. In the sense of a Feature model this would mean that the Feature JMS has to be integrated into the container that needs to be generated. So basicly to summarize things up the following process could be outlined to transform an EJB application into a leightweight application that runs on a MIDP device.
-
Analyze/Parse an existing EJB.
-
Transform the EJB into a component that fits into the above Feature Model.
-
Generate an application container according to the Feature requirements of the component.
This section is not just a theoretical section. Generating or converting Desktop applications into J2ME compliant applications is possible. As a result of the research efforts for this diploma thesis, it could be figured out that for example Wallez is able to dynamically convert the current Cocoon system into a system that runs on PersonalJava [[baumgarten, LUCA02]]. This example demonstrates that it is even possible to dynamically tranform server applications by using some kind of a generative approach.
Application will be deployed onto mobile devices according The J2EE Client Provisioning Specification, v0.95.
Basicly mobile clients are able to query a J2EE server for new applications that are available for their specific kind of device. As shown in the figure below deploying a mobile application onto a mobile device could be handled using different protocols according to the cappabilities of the client device. Laptop users for example could recieve their applications over the JNLP[17] protocol.
Every possible mobile application resides in a provisioning repository, which could be based on a RDBMS or some other kind of storage media. Additionally it would be possible to not store the applications locally but instead to use an adapter that access the applications stored in some sort of a third-party software management system.
|
|
|
|
|
|
|
|