How Stuff Works – WSO2 Carbon
By Isuru Suriarachchi
- 8 Mar, 2009
The WSO2 Carbon platform is the base framework for many WSO2 products. WSO2 Carbon leverages OSGi  framework technology, which makes the platform inherently dynamic and flexible. Carbon breaks down the barriers between different products, by packaging product funtions into components. Users can select the components that they need for a customized approach, or they can select packaged selections of components (standard product functionality). In addition, WSO2 Carbon can run standalone or on top of other application servers.
If you have already read the article “Getting Started with WSO2 Carbon”, then you already have a clear understanding of the dynamic and agile nature of Carbon. This article builds on this introduction, to provide a picture of how the Carbon platform works internally. It is recommended to have a reasonable knowledge on OSGi, especially bundles, OSGi services and bundle start levels, in order to make the most of this article. Please also note that this article is based on WSO2 Carbon v 1.5.1.
How Carbon Starts Up
WSO2 Carbon runs standalone and well as on other application servers like Tomcat, Websphere, WebLogic etc. In both cases, the actual Carbon server is started and run through a servlet called the “Bridge servlet”. After the initialization of the Bridge servlet, the execution process of Carbon is similar for both cases.
In order to enable WSO2 Carbon to run standalone, a Tomcat server is embedded within it. Tomcat-related jar files and other jars needed to start up the embedded Tomcat instance are placed in the CARBON_HOME/lib directory. The following figure shows the startup process of Carbon:
Startup Script - When the Carbon startup script (wso2server.sh or wso2server.bat) is run, it adds all jar files in the lib directory into Java classpath and calls the main() method in the org.wso2.carbon.server.Main class, which is found in org.wso2.carbon.server module.
Main Class - All the system properties are set here and org.wso2.carbon.server.TomcatServer class is called to start the embedded Tomcat server programatically.
Tomcat Server Starter - The transports.xml file in CARBON_HOME/conf directory is read, and the http and https transports are set up for the Tomcat engine according to parameters specified in transports.xml file. Other properties such as CATALINA_HOME are also set here, and the Tomcat instance is started. A repository listener is also started providing the CARBON_HOME/webapps file path.
Bridge Servlet - CARBON_HOME/webapps/ROOT/WEB-INF/web.xml file declares the all-important Bridge servlet through which the Carbon server is started. The Tomcat instance, which is already up, initializes the Bridge servlet. On initialization, it reads the following parameter in the web.xml:
<init-param> <param-name>osgiFramework</param-name> <param-value>equinox</param-value> </init-param>
OSGi framework launcher is selected according to this parameter. Carbon supports 3 different OSGi implementations. Equinox, Felix and Knopflerfish. As shown above, the default is Equinox.
Equinox Framework Launcher – CARBON_HOME/webapps/ROOT/WEB-INF/eclipse/plugins directory contains jar files (bundles) needed to start the Equinox OSGi framework. Framework Launcher reads the config.ini file, which is in CARBON_HOME/webapps/ROOT/WEB-INF/eclipse/configuration folder, and starts the OSGi framework accordingly. This file specifies the bundles to be initially started. The only Carbon-related bundle in it is org.wso2.carbon.bndmgt. Therefore, only that bundle is started (moved to ACTIVE state) at this stage.
All Carbon bundles are in CARBON_HOME/webapps/ROOT/WEB-INF/plugins directory and those are loaded by the framework and kept in RESOLVED state.
Bundle Management Agent (BMA)– Execution comes into BMA when its Activator is called by the OSGi framework. org.wso2.carbon.bndmgt.BundleManagementAgent implements the following interfaces which are provided by the OSGi framework.
BundleListener – Provides the bundleChanged method which can be used to catch an event when a bundle changes it's state.
FrameworkListener – Provides the frameworkEvent method which can be used to catch an event when the framework starts, on errors, on package refresh, start level changed etc. BMA focuses only on start level changed event.
In the config.ini file, BMA (org.wso2.carbon.bndmgt bundle) start level is set to 9 and the framework start level is set to 10. On startup, OSGi framework increases its start level one by one until the specified start level is met. All bundles which are found on the way are started. Therefore BMA is started when the framework start level is at 9. In the BMA Activator, it registers org.wso2.carbon.bndmgt.BundleManagementAgent as a BundleListener and a FrameworkListener. After the activation of BMA, OSGi framework increases its start level to 10. This event is received by the BMA as it has already registered itself as a FrameworkListener. This is the point in which all the other Carbon bundles are started. A start level is set to each and every bundle and the framework start level is increased such that it is higher than the highest bundle start level.
If BMA was not used, all the bundles to be started should be included in the config.ini file. It can be a pain when a user tries to add his own bundles into Carbon. In addition to that, currently some bundles must be started before the Carbon core. This is due to OSGi unawareness of Axis2. But this issue will be fixed in future releases of Carbon.
As mentioned above, all the other bundles are started by BMA. Some of the most important ones are listed below.
Registry Core – WSO2 Registry core is used as a repository for Carbon. When the Registry core starts up, it exposes Registry as an OSGi service such that any other bundle can use it.
Carbon Core – OSGi HttpService allows other bundles to dynamically register servlets within the OSGi environment. Carbon core registers the following servlets into it. These are initialized immediately after the registration.
Startup servlet – Starts up Axis2
Carbon servlet – CarbonServlet class extends AxisServlet and it is registered with the /service context. Therefore all requests coming into Axis2 services are forwarded to AxisServlet by this.
In addition, Carbon core deploys all modules and services which are in OSGi bundles using ModuleRegistry and ServiceRegistry. A service/module is identified by the services.xml/module.xml which is in the META-INF directory of the bundle. All administrative services and Axis modules are deployed here. New module and service additions are handled through the usage of BundleListeners.
HTTP Bridge – A very simple bundle which registers HttpServiceServlet in the BridgeServlet class as a servlet delegate. When the server runs, Bridge servlet delegates all the incoming requests into this HttpServiceServlet and it forwards those requests to the servlets which are registered under OSGi HttpService.
Carbon UI – Starts the Carbon UI framework by registering the Web context (default is /carbon) specified in the CARBON_HOME/conf/carbon.xml, to the OSGi HttpService.
This completes the startup process of WSO2 Carbon.
On Application Servers
In order to run Carbon on application servers, you have to create a folder (for example, foo) in the webapps folder and copy the WEB-INF folder of Carbon into that folder. When the server starts up, Bridge servlet is initialized and registered under the /foo context. So all requests that comes to /foo context are directed into the Bridge servlet when the server runs. Therefore, the startup process on application servers is exactly identical to the standalone case from the Bridge servlet onwards.
The following figure shows the high-level architecture of the Carbon server:
As shown in the figure above, Carbon runs entirely as a servlet in a servlet container. It can be the embedded Tomcat instance or any other application server.
Bridge servlet is the entry point for all incoming requests for Carbon. The servlet-mapping used for Bridge servlet is as follows (in web.xml):
<servlet-mapping> <servlet-name>bridgeservlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
According to this, all incoming requests are directed into Bridge servlet when Carbon runs. All these requests are delegated into the OSGi HttpServiceSevlet as it is registered in the Bridge servlet to act as a connector between the Bridge servlet and the OSGi framework.
All required contexts are registered in the OSGi HttpService, and it forwards requests to the appropriate context.
Back End Contexts
/services – Requests coming into Axis2 services. From this point onwards, Axis2 takes the responsibility of these requests and handles them according to the services and modules deployed in it.
Front End Contexts
/carbon – Requests coming into pages in the Carbon UI framework
/fileupload – Requests coming into file upload servlet
/filedownload – Requests coming into file download servlet
Carbon front end bundles communicate with the back end through Web services. All administrative services are deployed as Axis2 services. Therefore, Carbon front end and back end can be run as two different Carbon instances. This is a really cool feature when it comes to production servers.
In this article, we had an in-depth look at how the WSO2 Carbon server works internally to provide many attractive features for users. Carbon inherits many advantages of OSGi, such as dynamism, flexibility and extensibility. However, there are a few areas in WSO2 Carbon that need fine-tuning in order to make the most out of OSGi facilities.
 WSO2 Carbon
 OSGi Alliance
 Getting Started with WSO2 Carbon
 OSGi Specification
 Tomcat Servlet container
 WebSphere Application Server
 WebLogic Application Server
 Equinox OSGi implementation
 Felix OSGi implementation
 Knopflerfish OSGi implementation
Isuru Suriarachchi, Software Engineer, WSO2.Inc, isuru AT wso2 DOT com
- Isuru Suriarachchi
- Technical Lead and Product Manager
- WSO2 Inc.