XWiki - From Vision to Architecture

This week’s blogpost will be about the architecture design of XWiki. XWiki is a generic web development platform that is used for creating a diverse range of collaborative applications1. To get a good grasp of how the application is designed, different views of the platform will be discussed. We will start with its main architectural style, followed with a container view of the application. We will continue discussing its components and the connections between them. When the different components and connectors are discussed, we will talk about the development view and the run time view. Finally, we will discuss how the design of the application helps realise the quality attributes of the application and talk about the way other external sources can interact with the XWiki platform thanks to its API design principles.

The main architectural style

The main architectural style used by XWiki is morphing 2. While traditional applications are created from scratch by assembling different building blocks to create a working application, morphing takes a different approach. Morphing starts with an already functioning application, allowing developers to change it at run-time into the target application. This can be done by configuring, adding, and removing modules.

This brings a lot of advantages to XWiki. First, it allows for iterative, need-based development. The application can be used from day one and can be updated whenever new needs emerge. This allows for a flexible way of developing the application and makes it possible for the application to unfold itself over time into the application it needs to be. Secondly, it allows for continuous delivery of new features to the applications. Changing, adding, or removing modules can be done while running XWiki. Also, because of the neath division of the application into different wiki pages, other developers and designers can work on the application at the same time. Thirdly, it is efficient. When adding, changing, or removing new features, the result is immediately visible. There is no need for compilation or deployment and the effects can directly be checked.

Container view

XWiki applications consist of three different containers: the XWiki platform, the user application, and a Servlet container. These three parts are shown in the image below.

Figure: Container View of XWiki System (based on source)

The XWiki Platform contains all necessary functionality that is used for running the user application. This functionality is passed to the user application as small, mostly independent containers specialised in one specific task. These containers are called extensions and will be discussed more in more detail later in this blog. The XWiki Platform is responsible for managing these different extensions and allows user applications to access them when requested.

The user application consists out of two parts: the selected extensions from the XWiki platform and wiki pages. The extensions are provided by the XWiki platform and are added, changed, or removed by the developers of the application. The extensions contain functionality for the users of the application. This functionality is made available on different wiki pages, which can be accessed by its users.

Finally, the system consists of a Servlet container, managing the execution of the application. It bundles the different extensions provided by the XWiki Platform and handles the requests made by users and developers to the application.

Components view

Extensions are the components that make up XWiki. These provide all the functionalities that XWiki has to offer. Within the project, there exist over 600 extensions 2 and even though they are stored in the XWiki platform container, they can be accessed and used by other containers as well. Extensions are written in the Java programming language 2.

Extensions can be divided into two different classes, which are core extensions and non-core extensions. While core extensions are components that are necessary for XWiki to function properly, non-core extensions provide additional functionality, that goes beyond the core application of XWiki. An example of a core extension is the extension manager, which handles installing, updating, and uninstalling extensions in a running XWiki application.

XWiki users can create applications using a combination of core and non-core extensions. Such a set of extensions that can be used to achieve a certain purpose is called a flavor. An overview of such a flavor can be seen in the following figure.

Figure: Overview of a flavor

An overview of the architecture of extensions within XWiki can be seen in the figure below.

Figure: Architecture of XWiki extensions (based on source)

Furthermore, XWiki extensions are divided into categories, marking their purpose. These categories are API, Application, Authentication, Color Theme, Filter, Flavor, Icon Theme, Macro, Project, Skin, Syntax, UI extension and Other 3. These categories make sure that the large, and growing, number of extensions can be managed by XWiki users properly.

To some extent, there are dependencies between extensions. A flavor, for example, is by itself an extension that depends on other extensions. Also, non-core extensions depend indirectly on core extensions (and core extensions depend indirectly on other core extensions), as XWiki applications cannot work correctly without core extensions. However, next to this, there are not many dependencies between different extensions, because the extension manager, mentioned earlier, handles combining extensions to form a working XWiki application. Therefore, most extensions can exist independently of other extensions.

Extensions on their own are again made up of subcomponents. These can be either Java components (or Java classes) or wiki pages. The management of components is done by the XWiki component manager. Extensions that are made up of wiki pages are packaged as XAR files, while extensions made up of Java components are packaged as JAR files 2.

Connectors view

Extensions are connected and combined using the extension manager 4. An overview of how this works can be seen in the figure below.

Figure: Architecture of extension handling (based on source)

In this figure, it can be seen that extensions can be stored in one of several places: either in a local repository or on an external server. In the first case, the extension manager directly fetches the needed extensions from the local repository. In the second case, however, an extension called the repository manager receives the needed extension from a handler, which in turn fetches the extension from the external repository. These handlers can either be XWiki handlers for XWiki repositories, Maven handlers for Maven repositories or some other form of handler for other repositories.

The repository manager then passes the extension to the extension manager. The extension manager installs the extensions, removes redundant existing extensions, and potentially upgrades existing extensions. During this process, the extensions manager calls the component manager, such that the component manager can register the components that make up the installed extensions.

This approach of a centralised extension that handles the connection and combination of different extensions, reduces the number of dependencies between extensions and the amount of coupling between different extensions, because many extensions can exist independently of other extensions and do not require any form of interfacing with other components. This is especially the case for pairs of non-core extensions, as these should generally be able to work independently.

Development view

The source code of a release of XWiki does not originate from a single project. The development of XWiki is split into multiple top level projects with their own repositories. For the most recent releases, the XWiki product consists of the XWiki Commons, XWiki Rendering and XWiki Platform 5. The repositories of these projects can be found on the GitHub of XWiki.

Even though the top level projects of XWiki are dependent on each other, it is possible to work on the development of one project without having to build the others yourself. This is possible because XWiki uses a technique called binary dependency builds 6. With this technique, the dependencies do not have to build locally, but can be downloaded from a remote artifact repository. In the case of XWiki, the results of the builds of the projects are stored in their repository manager. In order keep the versions of the build up to date, a continuous build server is used. This will automatically update a build of a project whenever there is a new release. This way, developers can work on the development of parts of XWiki and easily test it with the most recent builds of the other projects it depends on.

Run time view

XWiki is a so called runtime platform. Where traditional, non-runtime platforms are created from scratch by creating different components and combining them into an application, runtime platforms approach this in a different way: runtime platforms are already running applications that can be configured during runtime to create the intended application 2.

For XWiki, this means the following: every XWiki application starts as a running application, only consisting of the core extensions of XWiki. This application can be seen as the bare minimum working version of XWiki based systems. According to the wishes of the developer and the application the developer intends to create, extensions can be added to this bare version during runtime, in line with the concept of morphing. Adding, removing, and upgrading extensions during runtime is handled by the extension manager.

In the XWiki documentation, there is no concrete and detailed overview of how the extension manager exactly performs these runtime configurations, but from other parts of the documentation, we can reconstruct the method of configuration globally: when the user adds an extension to the runtime of XWiki to create a certain application, the extension manager retrieves the extension from a repository, either local or external. Then, using the component manager, the extension manager determines the components that the extension depends on and injects these into the component class of the extension that is installed. When the extensions connected to these dependencies are installed as well, the new version of the runtime works. An overview of this can be seen below.

Figure: An overview of the runtime configuration of XWiki

Realisation of key quality attributes

In the previous blogpost, some key quality attributes were mentioned that XWiki should adhere to. This is done to ensure their user satisfaction and that their design goals are reached. The main attribute realised in almost every part of the XWiki architecture is flexibility. From the morphing architecture style to the hundreds of available extensions, XWiki’s architecture ensures it can adapt to any user requirements and environment changes.

Sometimes realising these quality attributes goes hand in hand with slacking a bit in another. One common trade-off could be flexibility and usability, when a system increases in flexibility to accommodate to a larger set of features and requirements, its complexity and with it its usability is influenced. However, XWiki offers the choice to include as many extensions as a user want to, which are all managed automatically and internally by the extension manager. The user can make use of everything XWiki and its extensions have to offer, inside of the user application, and its results are immediately visible. This way both flexibility and usability are realised.

API design principles

The XWiki platform is used in a bigger context to reach its users goals and must communicate with other external applications and is also built to be accessible for programmers who want to make use of its scripting. To make sure this can all be done with ease, XWiki developers have set Back-end Development Practices, Front-end Development Practices, Documentation Best Practices, JIRA Best Practices and more for themselves to make sure all code including the XWiki API adhere to API design principles.

When XWiki offers an API method to use in the scripting of a XWiki page, the XWiki development team guarantees it is safe to use by ensuring backward compatibility. If it is a relatively new method it comes with a warning that it can still change a bit, and it is not recommended to use internal classes as these can change any time. Deprecation rules are set for XWiki, and details and rationale for these rules are available for those interested.

To ensure uniform code practices and clear and expected uses of API methods (and the internal code base), there are naming conventions for classes, methods, and fields. XWiki developers follow the Oracle Javadoc coding conventions for its Java documentation. There is a set logger with rules to follow for its messages for clear communications with its user.

Recap

In this blogpost, we started by talking about XWiki’s main architectural style: Morphing, followed by a container view containing the XWiki platform, the user application, and a Servlet container. We continued discussing its extension components and the connections between them, where the extension manager plays a big role. Next, we looked at the project from a developer view, looking at the way the code is split into multiple projects and how this is built using a technique called binary dependency builds. Finally, we looked at how the design of the application helps realise the quality attributes of flexibility and usability and addressed how the XWiki platform implemented API design principles into their development.


  1. https://www.xwiki.org/xwiki/bin/view/Main/ ↩︎

  2. https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/Architecture/ ↩︎

  3. https://extensions.xwiki.org/xwiki/bin/view/Main/WebHome ↩︎

  4. https://extensions.xwiki.org/xwiki/bin/view/Extension/Extension%20Module%20Architecture ↩︎

  5. https://www.xwiki.org/xwiki/bin/view/ReleaseNotes/ ↩︎

  6. http://web.archive.org/web/20090423073100/http://blogs.codehaus.org/people/vmassol/archives/000953_binary_dependency_builds.html ↩︎