Jenny Liu
School of Information
Technologies
University of Sydney
[email protected]
JBoss is a free, open source J2EE implementation. Its architecture is highly modular and plug-in design. JBoss uses the industry standard Java Management eXtentions (JMX) to manage the JBoss components as well as provide services for EJB. Based on our previous research experience, we know there are great difference of performance and scalability among J2EE application servers. We believe the architecture design has an important role in determining the quality attributes such as performance and scalability. Analyzing and extracting architectural model from JBoss will provide us insights of its behavior and help us to build an accurate perdiction model on performance. In this project we analysis JBoss application server architecture especially on four susbsystems, JBoss EJB Container, JBossNS,JBossTX and JBossCMP. A reverse engineering tool is used to extract component/subsystem dependency from source code. Both the conceptual model and concrete model of the three JBoss subsystems are generated and the architectural styles used in JBoss design are discussed.
JBoss is a free, open source J2EE implementation distributed under the LGPL license. It provides the basic EJB container as well as EJB services such as database access(JDBC), transactions(JTA/JTS), messaging(JTS), naming (JNDI) and management support(JMX).Current release JBoss2.2.4 implements Enterprise JavaBean (EJB )1.1 and parts of 2.0 specification, JMS1.0.1, Servlet2.2, JSP1.1, JMX 1.0, JNDI1.0, JDBC1.2 and 2.0 extensions (Connection Pooling also supported), JavaMail/JAF,JTA1.0 and JAAS1.0. It is 100% pure java and can run on any platform [1][2][3].
JBoss architecture is special compared to other J2EE
application server architecture.The modular architecure of JBoss is on the top
of JMX infrastructure. The figure below shows the major JBoss components
interating on JMX.
JMX is a reusable framework that can expose the applications to the remote or
local management tools[8]. Its architecture is layered. There are
instrumentation layer, agent layer and distribution layer. The distribution
layer is still waiting for future specification. Briefly, the user provides the
instrumentation of a given resource using managed beans,MBeans. The
instrumentation layer instruments the resource about its features and exposes it
to the JMX compliant application. They agent layer controls and exposes the
managed resources that are registered with the agent by MBeanServer.
The major JBoss modules are manageable MBeans connected by the MBean server [2].
JBoss EJB container is the core implementation of JBoss server. It has two features. It generates the stub and skeleton class of EJB object at the runtime and it supports hot(re)deployment.
JBossNS is the JBoss naming service to locate the object and resource. It implements JNDI J2EE specification.
JBossTX is a transaction monitor with JTA/JTS support.
Deployment service supports deployments of EJB jars, Web application archives(wars) and enterprise application archives(ears). It watches the URLs for J2EE archives and deploy the archives as they appear or change.
JBossMQ is the implementation of Java Messgaing Specification(JMS).
JBossSX supports both non-JAAS and JAAS based security implementations.
JBossCX implements parts of JCA. JCA specifies how J2EE application components can access connection-based resources.
WebServers supports Web containers and sevelet engines.The 2.4.x version of JBoss Tomcat 4.0.1,Tomcat 3.2.3 service and Jetty 3.x service
When JBoss starts up, it creates an MBean server instance in one of the first steps. The manageable MBean components are plugged into JBoss by registering with the MBean server. JBoss implements the dynamic classloading M-Let services, which is an agent service. It allows to register the MBeans to the MBean server. The MBeans to be loaded are specified in a text based configuration files.
The JMX MBean server doesnt perform much functionality actually. It works as a microkernel aggregator component which interconnecting the MBeans. The functionality is provided by MBeans instead of JMX MBean server. The overall architecture of JBoss can not be strictly categorized as the architecture styles in Garlan and Shaw's paper[12]. Instead, it is a component plug-in framework. The interface of MBeans is the connector.
In the rest of this report, we will choose the JBoss EJB container, JBossNS, JBossTx and JBossCMP subsystems of JBoss architecture for our study. Although JBossCMP,container management of persistence of entity bean is a part of container architecture, we discussed it seperately, because it has its own architecture. The reason we only cover these parts in this project is they are of major concerns of our work on performance evaluation of JBoss application server. The methodology used in this project enables to include more subsystem into the study if needed.
JBoss EJB Container is the core implementation of JBoss
server. Figure 3-1 shows the conceptual model of EJB container. We can see that
the architecture of JBoss container is not a strict layout. Most dependencies
are bi-directed and the container depends on much lower level components. In
fact, the Container and its Plugins, InstancePool,
InstanceCache, Interceptor, EntityPersistenceManager,
StatefulSessionPersistenceManager, form a plugin framwork [14] to
provide EJB services to a particular EJB.
3.1.1 Major Componemnts and Interfaces
The client doesnt access to the ejb instance direclty rather than interacts with home (EJBHome) and remote ojbect (EJBObject) interfaces provided by the container. The Container forward the calls from client to bean instance to perform operations. It is the container's responsibility to interact with plugins, provide information for plugins to perform operations and manage the lifecycle of beans. There are four subclasses of Container, namely, StatlessSessionContainer, StatefulSessionContainer, EntityContainer and MessageDrivenContainer. They are created and initialized at the deployment time by the ContainerFactory according to the bean type.
A ContainerFactory is used to create EJB container and deploy EJB into
the container. ContainerFactory is implemented as a MBean. That means its
services start as the JBoss server starts. It can be given a URL to an EJB-jar
XML file. ContainerFactory use the metadata in EJB-jar XML to instantiate
containers and make them available for invocation. During the deployment, the
functionality of ContainerFactory includes:
ContainerInvoker is a Java RMI server object. As it name indicate, ContainerInvoker will invoke the container for the method invocation representing of client request. It is interface between client request and container. It utilizes the RMI exporting to make itself available to accept calls from both remote clients living in other JVMs and from other beans of the same EJB application within the same JVM. ContainerInvoker works in the communication layer and it can be associated with a particular protocol. With a new protocol introduced into JBoss server, one just need to provide a ContainerInvoker implementation of that protocol. JBoss communication layer replies on Sun's RMI using JRMP. The RMI of version of ContainerInvoker is JRMContainerInvoker. A ContainerInvoker seperates the communnication protocal with the EJB implementation. This increases the system modifiablity. The protocol used by JBoss EJB container can be specified in the server configuration files.
EJB object instances can be pooled to reduce the overhead at run time to creat them. A pooled instance is not associated with any ejb object. They are managed by InstancePool.
Stateful session bean and entity bean instances can be cached. They have states in their life-cycle. A cached instance is obtained from instance pool and associated with a particular object and has an identity. The states are handled by InstanceCache, such as synchronization of the instance state in cache and in second storage.
EntityPersistenceManager is responsible for the persistence of entity bean.
StatefulSessionPersistenceManager is responsible for the persistence of stateful session bean.
Inteceptor accepts the method invocation forwarded by container. In
the container configuration standardjboss.html file, the interceptors that the
method invocation must pass through are defined in order. Figure 3-2 shows the
logic execution of the method invocation passing through the interceptors:
This conforms with the 'pipe and filter' architecture defined by David Garlan
and Mary Shaw[12], in which a prototypical filter is a component that takes in a
stream of data and incrementally computes output such that output appears before
the input stream has been completely read in. The interceptors are filters and
the invocation method is the connector between sucessive interceptor.
Interceptors benefit from this architecture:
3.1.2 Dependency
Internally, InstancePool, InstanceCache, EntityPersistenceManager, StatefulSessionPersistenceManager, Interceptor are interfaces for container Plug-in. Container Plug-in is a collection of the implementations of these interfaces. JBoss container doesnt do much significant work other than provide a framework to connect various plugins:
When performing the client request, the container framework has external dependency on other service modulars, naming service, transaction service, security service and resource management. For example, when a client request has a transaction context update the data in database, the container need to contact naming service get the datasource and resource management provide the drive for that datasource. The transaction processing among the container, transaction manager and resource manager is controlled by transaction service.
Unlike traditional distributed system architecture, EJB container has externilized attributes declared in the deployment description files. Alought a container acts corresponding to these metadata information, its external dependency on the deployment service is a little different from other services. That means this information is set to the container at deployment time.
3.2.1 Major JNDI API
JNDI provides varities of naming services. The major JNDI API are
javax.naming.Name, javax.naming.Context, javax.namingInitialContext. Basically a
naming system is a colletion of object and each object has unique Name. Context
is the interface for client to interact with a naming service. InitalContext
implements Context. JBoss naming service is the JBoss JNDI provider. The source
code is in the org.jnp package. As we have mentioned in section 2, JBoss
naming service is implemented as MBean. Figure 3-2 shows the conceptual model of
JBoss naming services.
3.2.2 Major Components and Interfaces
The org.jnp.server package contains the MBean of naming service, Main. Main wraps NamingServer and expose it. NamingServer does the job of name-object pair query.
The org.inp.interface package extends/implements javax.naming.* interfaces. The interface can be access remotely from client. It is interconnected with Main to access naming service in NamingServer. NamingContext is a implementation of javax.naming.Context and it is the interface between client and JBoss naming service.
3.2.3 Dependency
3.3.1 Major Components and Interfaces
BossCMP extends the JAWS to support the mapping between java object in memory
and the relational data base storage. JBossCMP consists of the components to
support EJB 1.1 Container Managed Persistence (CMP) model. In entity bean model
of CMP, the persistence of the EJB instance state is performanced by the
container. The container accesses the Database on behalf of the entity bean.
Figure 3-4 shows the JBoss CMP services conceptual model
EntityContainer depends on EntityPersistenceManager interface for the persistence management of entity bean.
CMPPersistenceManager implements EntityPersistenceManager interface. As we mentioned before, the container manages the instance states. The semantics of EJB1.1 CMP callback methods, ejbLoad, ejbStore, ejbActivate, ejbPassivate, ejbRemove provides the container point of view of the instance state. Actually it is the CMPPersistenceManager that does the synchronization of cached instance states with underlying database. For example, when the bean cached data is loaded, CMPPersistenceManager will invoke container's callback method ejbLoad on the bean instance. When the cahced data needs to update the database, ejbStore method is invoked to prepare cached data and then CMPPersistenceManager will take care to update the dabase.
EntityPersistenceStore interface implementation takes care of the details of a particular physical store. CMPPersistenceManager delegates the actual storage of the entity persistent fields to EntityPersistenceStore. Notice that EntityPersistenceStore is an interface and this leaves space for persistence storage of customization, e.g. file based storage or database storage.
3.3.2 Dependency
Externally, JBossCMP may depends on JBossNS to get a reference of datasource to save the persistence data for bean instance.
3.4.1 Major Components and Interfaces
|
3.4.2 Dependency
The primary requirements of the transaction manager services is to bind its implementation to the JNDI naming directory when it is started by the service management of JBoss server. Therefore JBossTx externally depends on the JBossNS.
Since the developers tends to group files with similar functionality into package, we found that the hierarchy of the source code package is closed to the conceptual model. We rearrange the source codes by grouping the source codes in different packages with some expected dependency based on our conceptual model and put them into the together5.5.
The concrete architectural model is substantially different from our expection and knowledge of the conceptual model. Some components and dependency appear unexpected and some disappear. This is because the concrete model is from the implementation point of view which is closer to the run-time behavior than the conceptual model. In this section, we discuss the concrete model of container, naming service, container managed persistence service and transaction service.
4.1.1 The method to obtain a synthetic concrete model
Figure 4-1 shows the dependency digram of container and its plugins. The
concrete architecture model we got from Together5.5 is substantially different
from our knowledge of conceptual model. It is now layered architecture model
with the plugins implementation components in the top layer, container in the
middle layer and the plugin interfaces in the bottom layer. The dependecy
between interceptor and persistence manager disappear, which counters intuition
based on the JBoss documentation. We found this is due to the pitfall of
Together5.5 visualization of the relationship. The dependency of components in
the same layer, for example the one between entity instance interceptor and
entity instance, is omitted. To solve this problem, we use a method of following
steps:
|
4.1.2 Unexpected Components and Dependency
Here we only discuss the entity container architectual model.
StatelessSessionContainer and StatefulSessionContainer concrete architecutual
model are shown in appendix.
At the deployment time the ContainerFactory creates and initializes containers.The home object is generated as a dynamic proxy by JRMPContainerIvoker, whick we will discuss it later. The InvocationHandler is replaced by HomeProxy class.Then it is bound to JNDI naming tree with a specified JNDI name in the deployment descriptor file.
The proxy is serializible and it can be sent to the remote client across network. When a client looks up the EJBHome from JNDI and the home proxy instance is serialized. At the client side, the home proxy instance is unserialized. Becasue the proxy implements the bean's home interface, it can be cast and used as the home interface.
When a client requests a EJBObject using home object reference. The EJBObject dynamic proxy is generated by the code shown above. The InvocationHandler is replaced by the one of the EJB object proxies, namely, StatefulSessionProxy, StatelessSessionProxy and EntityProxy based on the bean type. The same as home proxy, EJB object proxy can also be serialized and sent to the remote client across network.
Fianlly the client gets the handle of EJB object and can use it to invoke business method implemented in server side beans. The home and object dynamic proxies forward the calls from client to InvocationHandler.
The persistence management of entity bean has two type, bean managed persistence(BMP) and container managed persistence(CMP). With BMP the programmer has to take care of the synchronization of bean cached state with underlying database while with CMP, the container generates the codes and free the programmer of such effort. Their effect on performance is beyond the scope on this report. We will discuss the JBossCMP architecture later.
Each XXXInterceptor is a implementation of Interceptor interface and they are container plugins. With entity bean, the EntityInstanceInterceptor, EntityLockInterceptor and EntitySynchronizationInterceptor use BeanLockManager for concurrency control on the bean instance.
Each ContainerPlugin implementation has depencency on the EntityContainer and it knows which container it is working for by setContainer() and getContainer().
There is such a need that ContainerInvokers may communicate with the Container, for example when a session bean invokes a method of entity bean. ContaineInvokerContainer is an interface for Containers that uses ContainerInvokers. JRMPContainerInvoker has a dependency on ContainerInvokerContainer, which is actually EntityContainer.
MethodInvocation is passed through all the components across the network. All the components have a dependency on it. MethodInvocation depends on EnterpriseContext, which is associated with the bean instance for the lifetime of the instance. In entity bean model, an entity bean is a java object representing the underlying database. CacheKey is an encapsulation of the PrimaryKey. EntityEnterpriseContext depends on CacheKey to get entity object and EntityProxy passes CacheKey as a parameter to the entity container. The entity container use CacheKey as an identity to locate the ejb object and delegate the calls to its instance.
The plugin framework of EJB container make it flexible and evolvable. One just need to write a new implementation of a particular interface if changes are needed.
4.1.3 An example of a EntityBean container and its plugins to performance method invocation
4.2.1 Unexpected Components and Dependency
org.jboss.naming.NamingService is implemented as a MBean. It provides the JNDI naming services. It is the NamingService that create Main MBean and manage its state. When the NamingService starts, it initializes and start Main MBean. NamingService delegates the functionality to Main Mean. This duplication of MBeans volialate our conceptual model, however, the reason behind the screen is that JNDI naming service in JBoss is implemented as a stand-alone application. The NamingService MBean embeds Main by creating a new instance. The benefit of this architecture is if the JNDI VM is the same as JBoss server VM, the JNDI operation will pass socket connect and reduce the overhead.
4.2.2 An example of a client to get ejb home object
In order to understand the JBoss naming service architecture better, we give an example and trace the call processing. For example, when a client tends to invoke a bean method, it has to locate the bean home first, which is the handle to create a bean object for the client request. The JNDI name of the home object is specified in deployment discriptor file at development time. A client can get object at the run time by contact the naming service with its JNDI name.
4.3.1 Unexpected Components and Dependency
Table 4-1 shows the interface method of EntityPersistenceStore, the
interfaces in org.jboss.ejb.plugin.jwas package used by
JAWSPersistenceManager to implement EntityPersistenceStore and the
lowest level implementation of those interfaces.
Method in EntityPersistenceStore |
Interface name | Implemenation name | Function |
createEntity | JMPCreateEntityCommand | JDBCCreateEntityCommand | called when an entity is to be created |
findEntity | JMPFindEntityCommand | JDBCFindEntityCommand | called when a single entity is to be found |
findEntities | JMPFindEntitiesCommand | JDBCFindEntitiesCommand | called when a collection of entities is to be found |
activateEntity | JMPActivateEntityCommand | JDBCActivateEntityCommand | called when an entity should be activated |
loadEntity | JMPLoadEntityCommand | JDBCLaodEntityCommand | called when an entity needs to be loaded from the underlying storage |
loadEntities | JMPLoadEntitesCommand | JDBCLoadEntitesCommand | called when a set of entities should be preloaded from the underlying storage |
storeEntity | JMPStoreEntityCommand | JDBCStoreEntityCommand | called when an entity needs to be written to the underlying store |
passivateEntity | JMPPassivateEntityCommand | JDBCPassivateEntityCommand | called when an entity is to be passivated |
removeEntity | JMPRemoveEntityCommand | JDBCRemoveEntityCommand | called when an entity should be removed from the underlying storage |
4.4.1 Unexpected Components and Dependency
TxManager implements the javax.transaction.TransactionManager and the above two interface. It is managed by the TransactionManagerService. TxManager depends on TransactionImpl to perform the transactional operations such as decarerating the transaction with begin, commit, rollback method. Interestingly, TransactionImpl is just a lightweigh frontend of TxCapsule. The operation in TxCapsule is controlled based on the method invoked in TransactionImpl. TxCapsule holds all the information relevant to a transaction. Callbacks and synchronizations are done in this class. It depneds on XidImpl to identify transactions.
Recall the conceptual model with bean mamaged JTA transaction in session
bean. In this model, javax.transaction.UserTransaction is needed. JBossTx
has a subsystem to implements UserTransaction interface in package
org.jboss.tm.usertx. Usertx is divided into two subsystems, client and
server and they interact through interface. It is a pure layered architecture.
ClientUserTransaction is the client-side UserTransaction
implementation. It will delegate all UserTransaction calls to the server
through UserTransactionSession interface.
UserTransactionSessionImpl implements UserTransactionSession in
the server side. It is for the remote client whose VM is not at the same
location as the transaction mananger. With the clients which operates in the
same VM as the server, ServerVMClientUserTransaction is the client-side
UserTransaction implementation that delegates all UserTransaction
calls to the TransactionManager of the server. Like almost every service
in JBoss, UserTransaction implementation is managed as a MBean. It is bound to
the JNDI location with JNDI name UserTransaction.
In this report, we discussed JBoss conceputal architectual model and concrete architectural model. We built a method to synthesize the concrete model by using reverse egineering tool and tracing the source code manually. We found that concrete model is substantially different from the conceptual model based on the documentation. This is because the concrete model is in the implementation level and it is more closed to the real story. It is the concrete model that release the special and ad-hoc design of JBoss application server. We tried to apply this method to COTS J2EE product. Unfortuantely, the source code is not available and reverse engineering result is not so complete thus misleading. Only the conceptual model can be compared with JBoss architectual model we got.
Although it is quite exciting to extract and analysis the JBoss architecture in the way we present in this report, this approach has its limitation. we still cannot get any conclusion of its effect on quality attributes, such as performance. This is because there is a great diversity of components and subsystem involved during the run time from the concrete model we got from static analysis. One possible solution is to instrument the source code to trace the componements involved during the run-time and measure their performance. In this way, the conceptual architectual model can be mapped to software exectution model, with the nodes representing the functional components of the software and the arcs represent control flow. The concrete architectual model can be mapped to system execution model, which represents the key computer resources as a network of queues[13]. Therefore it is feasible to evaluate the JBoss performance based on its architecture analysis. Our work on extracting JBoss architecture help us to understand the system greatly. The next step is to derive an analytical model of JBoss application based on this analysis, instrument codes to get measurements and evaluate its performance.