5.1
Copyright © 2007, 2008 Nuxeo SAS
Permission is granted to copy, distribute and/or modify this document under the terms of
the GNU Free Documentation License, Version 1.2; with Invariant Section “Commercial
Support”, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is available
at the URL: http://www.gnu.org/copyleft/fdl.html
Table of Contents
indexableDocType extension pointresource extension pointThe primary focus of this book it the presentation of Nuxeo EP, from the perspective of its configuration and its architecture.
This book is not an end-user manual for Nuxeo. If you are interested
in such a document, we recommend that you get it from http://doc.nuxeo.org/.
As a reference book for the Nuxeo platform, this book has several intended audiences:
System integrators, who need to understand how to configure and adapt the Nuxeo platform to their customers needs.
Third-party application developers, who will typically need both to customize the behavior of some components and to write new components to extend the functionalities of the platform.
System administrators, who need to understand how to configure the platform for the specific needs of their hosting environment.
Core developers, who work on the platform and need a reference documentation.
We fully understand that these different people with different concerns, and we plan to create, thanks to the modular structure of this document, more targeted books for these different people.
Readers of this book are presumed familiar with the Java 5 language and with the Java EE and XML technologies.
Founded in 2000, Nuxeo SAS is part of the "second wave" of open source companies, and focusses on developing and supporting applications, instead of system software or development tools.
By entering the ECM field early in 2002, Nuxeo has established itself as the leader of open source ECM, with customers for critical projects in the Government, Energy and Finance sectors. Nuxeo currently has 40 employees, about half of them developers.
Nuxeo has customers and partners in Europe, in Northern and Southern America, in Africa and in India.
This chapter will give you an overview of ECM and the motivation for using the Nuxeo platform in your next ECM project.
According to the AIIM, the Association for Information and Image Management, ECM is defined as "the technologies used to capture, manage, store, preserve, and deliver content and documents related to organizational processes".
A March 2005 white paper on “The Hidden Costs of Information Work” by the IDC in the United States found that the average office employee spent approximately one day per week organizing and filing documents that they used. This can equate to a considerable amount of cost and inefficiency. A further twelve hours was spent on managing document approval, managing document routing and publishing to other channels. Nine hours was spent searching for documents.
Nuxeo EP 5 is the 5th version of the open source platforms developed by Nuxeo (the four previous ones where known as "CPS").
Nuxeo EP or "Enterprise Platform" is the server part of Nuxeo EP 5. It is a Java EE application intended to run in a standard Java EE 5 application server like JBoss. It can be accessed by end users from a web browser, from office productivity suites like MS-Office or OpenOffice.org, or from rich client developed using the Nuxeo RCP technology (see below).
Nuxeo RCP or "Rich Client Platform" is a platform for building rich client applications, that usually connect to a Nuxeo EP server.
Nuxeo EP and Nuxeo RCP run on top of a common runtime, "Nuxeo Runtime", and share a common set of core components, called "Nuxeo Core".
This chapter describes how to setup a development environment for working on Nuxeo EP. It currently deals with an Eclipse environment and will be completed soon with Netbeans and IDEA.
You will see how to easily start a new project. If you encounter a problem don't forget you can share your experience on the ecm mailing list.
We assume from now on that on your computer, you have the following ready-to-use environment:
Java Development Kit (JDK) 1.5.x (Nuxeo EP is known to work now with Java 6 or OpenJDK, but this is currently not supported)
Apache Ant 1.7.0 (or later), from http://ant.apache.org/.
Maven 2.0.8 (or later, not Maven 2.0.7), from http://maven.apache.org/.
Eclipse 3.3
A Nuxeo EP installation from the last release (download the installation
wizard). You can also download a nightly build installer from http://www.nuxeo.org/static/snapshots/ but keep in mind that
this one may be broken, so don't erase your working setup with a nightly build: the
result is not guaranteed.
Note : The Nuxeo EP installer also installs and sets up the right version of JBoss on your computer, so you don't need to install it by your own.
If some of these software are not already set up on your computer, please refer to Appendix B, Detailed Development Software Installation Instructions, where you will find useful help.
Before starting, if for you mvn sounds like an other more boring acronym to learn, you should read these few lines, otherwise, you can skip it and go to the next step.
Maven is an IT project helper, that structures the development process in many ways:
it helps you using always the same code organization, so that everybody in the company works the same way
it allows you to apply in an easy and standard way many tools to your application and your application source: tools for testing, quality, deployment, documentation site generation, etc.
it simplifies a lot the way you manage dependencies in your projects by using the pattern of public / local repository.
Depending on how deep you will go with Nuxeo, you may use part or all of the
aforementioned items. But for now, we will have special attention for
repositories, pom and
dependencies. When you start a project under eclipse, you usually begin
by downloading then adding all the libraries you will need, and put them all in a
subdirectory of the project. You may have some libraries copied many times, like
JUnit. And after some time you may end up with many versions of
the same libraries in different places of your projects.
Maven is really useful for that. When you
start a project, you create a pom.xml which will contains all the
information Maven needs to act. Especially, it will contain the dependencies of your
project. The dependencies are the libraries you usually add with the "add external jar"
command under Eclipse. In Maven terminology, it is called an artifact.
So you specify in pom.xml which artifacts you need and which version.
At compilation time (of course with Maven) it will automatically find the jar corresponding
to the artifacts specified, so that there are no "no class found" error.
How does Maven know where to find it?
Maven uses repositories of artifacts (libraries) One of the goals
of Maven is to gather all of the code production in the same place, in company or public
scoped repositories, so that everybody shares the same libraries and knows where to find
them. There are the official an public Maven repositories, automatically inspected when
using Maven, but you can also set up private repository like Nuxeo's. You declare the repositories
you want your Maven installation to look up into in
$HOME/.m2/settings.xml. Maven will download the needed dependencies
from those specified repositories into the $HOME/.m2/repository
directory, that acts as a "cache".
Then, suppose you want to compile your project with Maven. Maven will read the
POM, see that it needs, for instance the JUnit library. It will check
if this library is present in the local Maven repository $HOME/.m2 and
if not, it will check in a remote one. For sure, it will look into Maven repository, and
maybe some private remote repositories you might have set up in your
$HOME/.m2/settings.xml file. At compilation time, if your code uses a
JUnit TestCase class, it will know it has to go to the repository to download
the dependency.
If you manage all your projects with Maven, you will save a lot of time at the beginning of the project, and your deployment procedure will be more reliable. So Nuxeo is developed through a full Maven process. And we encourage people who wants to develop over Nuxeo to also use Maven.
To achieve this, when you start a new project with Nuxeo, you will have to create your
own pom.xml that will reference Nuxeo libraries, for document
manipulation, etc. A POM represents a project, a resource, and has three main
characteristics: its name, its domain and its version. Then it has a lot of XML to specify
everything you want. For a Nuxeo project, you have to reference Nuxeo artifacts. So starting
a new project with all this structure is tedious and always the same.
To avoid doing the Maven packaging by hand, we prepared for Nuxeo platform users a
Maven archetype, that acts as a template system: we defined the
typical structure and POM of a Nuxeo Customization project and then, typing a command as
short as mvn archetype and a few parameters, Maven will auto-generate the
structure of your project, and you are sure it will be Nuxeo compliant.
You can also read the Wikipedia entry for Maven and the Maven archetype introduction for more information about archetypes.
The goal of the nuxeo-archetype-start template is to setup a development environment to work on a Nuxeo EP plugin.
The default code provides: a maven layout for sources, tests and dependencies, a Ant target for deployment. It also customizes the web application a litte bit.
To create a project named my-project in the
com.company.sandbox.myproject package:
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \
-DartifactId=my-project \
-DgroupId=com.company.sandbox.myproject \
-DarchetypeArtifactId=nuxeo-archetype-start \
-DarchetypeGroupId=org.nuxeo.archetypes \
-DarchetypeVersion=5.1.4 \
-DremoteRepositories=http://archiva.nuxeo.org/archiva/repository/nuxeo_release
You can see that you need to supply six arguments:
artifactId: the name of your project, usually with '-' to separate the words if there are many.
groupId: the domain name of your project. Usually it is the package parent name of your classes, you should use '.' to separate the words ('-' is not supported here).
archetypeArtifactId: the maven archetype artifact id. To generate a new project, Nuxeo provides you with nuxeo-archetype-start
archetypeGroupId: unique for all nuxeo maven archetypes : org.nuxeo.archetypes
archetypeVersion: the version of the archetype which is equivalent to the version of Nuxeo EP without the GA or RC part. (5.1.4, ...).
remoteRepositories: the repository location to download the archetype.
The warnings you see when creating your project are expected. If you see BUILD SUCCESSFUL at the end, your project was created successfully.
You should have the following source layout:
my-project
|-- README.txt
|-- build.properties.sample
|-- build.xml
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- company
| | `-- sandbox
| | `-- myproject
| | `-- DocEventListener.java
| `-- resources
| |-- META-INF
| | |-- MANIFEST.MF
| | `-- ejb-jar.xml
| |-- OSGI-INF
| | |-- deployment-fragment.xml
| | |-- event-listener-contrib.xml
| | |-- l10n
| | | |-- messages.properties
| | | |-- messages_en.properties
| | | `-- messages_fr.properties
| | `-- theme-contrib.xml
| |-- nuxeo.war
| | `-- img
| | |-- default_logo.gif
| | `-- login
| | `-- login_01.jpg
| |-- seam.properties
| `-- themes
| |-- nxfonts.properties
| `-- theme-sample.xml
`-- test
|-- java
| `-- com
| `-- company
| `-- sandbox
| `-- myproject
| `-- TestDocEventListener.java
`-- resources
|-- META-INF
| `-- MANIFEST.MF
`-- log4j.properties
You should create a build.properties file on
the base of the build.properties.sample so that
jboss.dir points to your jboss path. This
build.properties file will be used by
Ant to send the packaged file in the good
directory at deployment time. Note that when using the Nuxeo EP
installer, the JBOSS home directory is the same as the Nuxeo EP home
directory.
If you try to import your project into Eclipse right now, you will see many errors in
the source. This is because Eclipse is unaware of the classpath. Indeed when you (used to
;-) ) do the "add library" operation from Eclipse, it creates into the project directory a
.classpath file. So Maven (thanks to a plugin it will auto install)
generates this file for you, providing that you execute the following commands, at the root
of your newly created project:
mvn install mvn -Declipse.workspace=/the/full/path/to/your/workspace eclipse:add-maven-repo mvn eclipse:eclipse
The mvn eclipse:eclipse can be quite long
as it download all available package sources, this can be configured with
the downloadSources property in the
pom.xml file.
Now you can run Eclipse, and import the project from the file system as you are used to:
Then go back to the Java perspective and import the projects you have previously checked out as eclipse projects:
File > Import > General > Existing Projects Into Workspace
You can see on the left the Nuxeo project structure (directly inspired from Maven project structure) and you can browse the classes without errors.
You can navigate in the whole Nuxeo EP sources if you have keep the
downloadSources option.
Note: if you still have errors, it might be that the M2_REPO variable
has not been set up correctly. This variable should point to your home Maven repository,
generally here : $HOME/.m2/repository. To check, create or update this
variable in Eclipse, right-click on your project, choose "properties". Then in the "Java
Build Path" entry, click on "Add variable" (see here for detailed instructions).
Now that you have created your new custom project, you would want to see what your (not so tough) work produced? As easy as one line of command!
On your project root folder (provided you created the right build.properties, as mentioned earlier):
ant deploy
This will run Maven, install the needed dependencies if needed, compile the code, do the packaging and copy it onto the server directory.
Run your server (.../NUXEO_HOME/bin/run.sh or .bat), go to
http://jboss_host:8080/nuxeo/
Try to log with Admin signature (Administrator/Administrator) and to create a new document: if your project was correctly deployed, you should now see a "Book" document type.
Do you still find mvn as a boring command? :-)
The xhtml pages refresh period is controled by facelets and set by default to -1 (no refresh) for performance reasons. When developing, you will find it useful not to have to restart jboss when performing changes in xhtml pages. Since releases 5.1.5 and 5.2-M2, you can add the line "facelets.REFRESH_PERIOD=2" to the nuxeo.properties file in the nuxeo.ear/config folder: pages will be refreshed within 2 seconds.
The nxthemes framework has its own caching, so do not forget to hit the "refresh" button in the themes management page for changes to be taken into account outside of the "main" themes fragment at the center of a nxtheme page.
Nuxeo provides a sample project that you can find at org.nuxeo.project.sample. This sample project implements more customizations: a new document type, a new action, a new event listener, etc. Play with this example to start learning Nuxeo.
This Nuxeo Book is getting to be the most complete source of information around Nuxeo EP, both for beginners and advanced developer. It is a good start.
The extension point documentation is also very useful: although you may find it rough, it is the best way to evaluate the Nuxeo extensibility potential, and one should always start with a quick look around all the extension points, to "think Nuxeo" before starting a new project, and not reinventing the wheel.
The wiki: we try to reference all the documentation from the wiki welcome page, and you will find tricks, howtos, etc. If you want to have a writer account to help update the content, ask on the Nuxeo's mailing list.
The JBoss IDE has been morphed into the JBoss Tools (aka Exadel Studio, aka Red Hat Developer Studio). We're going to evaluate this new offering to understand how it can fit into the Nuxeo development process.
The JBoss IDE offers many useful features when dealing with JEE 5 projects, for creating EJB, managing Hibernate, etc. Especially, the JBoss IDE packaging contains JBPM Designer. You would want to use JBPM designer for writing new workflow procedures to leverage the default embedded JBPM implementation of Nuxeo EP workflow abstraction layer.
Here are the references for the Eclipse Update Manager:
Name: EMF Update Manager Site URL: http://download.eclipse.org/modeling/emf/updates
Name: JBoss IDE URL: http://download.jboss.org/jbosside/updates/development
The second site has dependencies on the first one: use the "Select required" to check EMF automatically when selecting JBossIDE.
Use case: suppose you just deployed Nuxeo EP on your JBoss server and run into a new crash or any unexpected behavior. Instead of stopping the server and rerunning inside Eclipse to reproduce the bug in the debugger, you can setup a new remote debugging profile for Eclipse.
Linux: edit /opt/jboss/bin/run.conf, add the following line
at the end of the file and restart
JBoss.
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
Windows: edit JBOSS/bin/run.bat, modify the line:
rem set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y %JAVA_OPTS%
by erasing the remark ('rem'), and disabling the suspend ('suspend=n'). You should have:
set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n %JAVA_OPTS%
Restart JBoss.
Then from Eclipse create a new debugger profile in menu > create a new Remote Java Application profile and set the source to the filesystem directory that host your complete Eclipse workspace and set the port to 8787.
Then edit the offending source code file and set breakpoints and run your new remote debug profile. From your web browser, refresh the page that was crashing and look back into Eclipse: the debug perspective should open automatically at your fist breakpoint.
Many Eclipse plugins allow you to browse JCR compliant repositories (the very back-end of Nuxeo uses, as a default storage system, the JackRabbit JCR reference implementation repository.
JCR Browser is available here: http://sourceforge.net/projects/jcrbrowser/
IntelliJ IDEA from Jetbrains is a very lovable IDE for Java that has many fans in the Java developers community. It is unfortunately not open source.
To start using IDEA for coding on the Nuxeo project, you just need to type mvn
idea:idea from your top-level source directory: Maven will download all the
dependencies, then generate the configuration files needed by IDEA and you will be able open
nuxeo-ecm.ipr from IDEA.
At the time of this writing, IDEA will report some (spurious) compilation failures and you won't be able to compile the whole application from IDEA. You can still use IDEA with the current configuration to write Java code ("with pleasure"), and use Ant and/or Maven to build/deploy the application.
When we started building Nuxeo EP, we defined several goals to achieve. Because these goals have a structural impact on Nuxeo EP platform it is important to understand them: it helps understanding the logic behind the platform.
An ECM platform like Nuxeo EP can be used in a lot of different cases.
The deployment of Nuxeo EP must be adapted to all these different cases:
Standard ECM web application
This is the most standard use case. The web browser is used to navigate in content repositories.
All services are deployed on an Application server
In order to be easily hostable, the platform need to be compatible with several application servers
Complex edition or rich media manipulation
In this case having a rich client that seamlessly communicates with other desktop applications and offers a rich GUI is more comfortable than a simple web browser.
Interface is deployed on a rich client on the user desktop
Services and storage are handled on the server
Offline usage
In some cases, it is useful to be able to manipulate and contribute content without needing a network connection.
GUI and some services (like a local repository) need to be deployed on the client side
Server hosts the collaborative services (like the workflow) and the central repository
Distributed architecture
In order to be able to address the needs of large decentralized organizations, Nuxeo EP must provide a way to be deployed on several servers on several locations
Scale out on several servers
Dedicate servers to some specific services
Have one unique Web application accessing several decentralized repositories
Use Nuxeo EP components from another application
When building an business application, it can be useful to integrate services from Nuxeo EP in order to address all content oriented needs of the application.
Provide web service API to access generic ECM services (including repository)
Provide EJB3 remoting API to access generic ECM services (including repository)
Provide POJO API to generic ECM services
There are certainly a lot of other use cases, but mainly the constraints are:
Be able to choose the deployment platform: POJO vs Java EE
As first deployment targets we choose
Eclipse RCP: a rich client solution that uses a POJO (OSGi) component model
JBoss Application Server: a Java EE 5 compliant application server
Be able to choose the deployment location of each component: client side vs server side
The idea is to be able to deploy a component on the server side or on the client side without having to change its code or its packaging
Before building Nuxeo EP we worked during several years on the Zope platform with the CPS solution. CPS was deployed for a lot different use cases and we learned a lot of good practices and design patterns. Even if Nuxeo EP is a full rewrite of our ECM platform, we want to keep as much as possible of CPS good concepts.
Concept of schemas and documents
Inside CPS most of the data manipulated was represented by a document object with a structure based on schemas.
This concept is very interesting:
Schemas enforce structure constraints and data integrity but also permit some flexibility.
When defining a schema you can specify what fields are compulsory, what are their data type, but you can also define some flexible part of the schema.
Share API and UI components for Documents, Users, Records ...
Because the Document/Schema model is very flexible it can be used to manipulate different types of data: like Users, Records and standards documents.
From the developer's perspective this permit using the same API and be able to reuse some UI components
From the user's perspective it give the application some consistency: because the same features and GUI can be used for all the data he manipulates.
Actions and Views
Because CPS was very pluggable, it was possible to easily define different views for each document type and also to let additional components contribute new actions or views on existing documents.
Nuxeo EP has a similar concept of views and actions, even if technically speaking the technologies are different.
Lazy fetching and caching
Because ECM applications make a very intensive use of the repository and often need to fetch a lot of different documents to construct each page, the way the document retrieval is handled if very important to have a scalable application.
With CPS we worked a lot on caching and lazy fetching.
With Nuxeo EP we incorporated this requirement from the beginning:
Distributed caching
Lazy fetching on schemas and fields
CPS was constructed as a set of pluggable components relying on a common platform. This modularity has been maintained in the new platform. Deploying a new feature or component on the new platform is as simple as it was on the old one.
This requirement as a huge impact on the platform because the Java packaging model and the Java EE constraints are not directly compatible with it.
Adding a new component should be as simple as dropping a file or an archive in some directory without having to rebuild nor repackage the application.
This is important from the administrator point of view: be able to easily deploy new features.
This is also very important from the support point of view: be able to deploy customized components without taking the risk of forking the platform and maintain the possibility to upgrade the standards components.
The CPS framework was powerful but we know it was very complex to use. Not only because of the unusual CMF/Zope/Python programming model, but also because there was a lot of different concepts and you had to understand them all to be able to leverage the platform when building a new application on top of it.
Nuxeo EP aims at simplifying the task of the developer
Clearly separate each layer
The idea is to clearly separate presentation, processing and storage so that developers can concentrate on their task.
Offer plugin API and SPI
Nuxeo EP is constructed as a set of plugins so you can modify the behavior of the application by just contributing a new plugin. This is simpler because for common tasks we will offer a simple plugin API and the developer just has to implement the given interface without having to understand each part of the platform.
Rely on JAVA standards
We try to follow as much as possible all the Java standards when they are applicable. This will allow experienced Java developers to quickly contribute to the Nuxeo EP platform.
We know what it's like to have to build and maintain an entire framework starting from the application server. With the switch to the Java technology, we will use as much as possible existing open source components and focus on integrating them seamlessly in the ECM platform. Nuxeo EP is a complete integrated solution for building an ECM application, but Nuxeo won't write all infrastructure components. This approach will also make the platform more standards compliant.
Thus developers can optimize their Java/JEE and open source experience to use Nuxeo EP.
Because ECM applications often need to be deeply integrated into the existing SI, Nuxeo EP will be easily integrable
API for each reusable service or component
Depending on the components, this API could be POJO, EJB3, or WebService, and in most cases it will be available in the three formats.
Pluggable hooks into Nuxeo EP
This mainly means synchronous or asynchronous events listener that are a great place to handle communication and synchronization between applications.
The Nuxeo EP platform was rewritten from the ground with the switch to Java. But we don't plan to do this kind of work every couple of years, it wont be efficient neither for us, nor for the users of the platform. For that reason, we choose innovative Java technologies like OSGi, EJB3, JSF, Seam ....
All the design goals explained just before have a huge impact on the Nuxeo EP architecture. Before going into more details, here are the main concepts of Nuxeo EP architecture.
Nuxeo EP is built of several layers, following at least the 3 tiers standard architecture
Presentation layer
Handles GUI interactions (in HTML, SWT ...)
Service layer
Service stack that offers all generic ECM services like workflow, relations, annotations, record management...
Storage layer
Handles all storage-oriented services like document storage, versioning, life cycle ....
Depending on the components, their complexity and the needed pluggability, there can be more that 3 layers.
This layering of all the components brings Nuxeo EP the following advantages
Choose the deployment target for each part of a component
By separating clearly the different parts of a feature, you can choose what part to deploy on the client and what part to deploy on a server.
Clear API separation
Each layer will provide its own API stack
Components are easier to reuse
Because the service and storage layers are not bound to a GUI, they are more generic and then more reusable
Thanks to this separation in component families you can easily extract from Nuxeo EP the components you need for your application.
If you need to include Document storage facilities into your application you can just use Nuxeo EP Core: It will offer you all the needed feature to store, version and retrieve documents (or any structured but flexible dataset). If you also need process management and workflow you can also use Nuxeo EP Workflow service. And finally, if you want to have a Web application to browse and manage your data, you can reuse the Nuxeo EP Web layer.
The targeted platform do not provide the same mechanism to handle all the deployment tasks:
Packaging (Java EE vs OSGi)
Dependency management
Extension management
Because of these differences, Nuxeo EP provides a unified deployment service that hides the specificity of the target platform. This is also a way to add a pluggable component deployment system to some platform that don't handle this (like Java EE).
This is one of the motivation for the Nuxeo Runtime that will be quickly introduce later in this document.
In Nuxeo EP, an ECM application is seen as an assembly of components.
This assembly will include:
Existing generic Nuxeo EP Components
Extensions or configurations contributing to generic Nuxeo EP components
Specific components and configuration
Inside Nuxeo EP each feature is implemented by a one or several reusable components and services. A feature may be implemented completely at storage level, or may require a dedicated service and a dedicated GUI.
Nuxeo EP Web application is a default distribution of a set of ECM components. This can be used "as is" or can be the base for making a business ECM application.
If you need to remove a feature
Just remove the component or deploy a configuration for disabling it.
If you need to change the default behavior of one component
You can deploy a new configuration for the component .
Declare a new Schema or define a document type
Configure the versioning policy
Deploy new workflow
...
This configuration may use an extension point to contribute the new behavior.
Contribute a new security policy
Contribute a new event handler
Deploy a new View on a document
...
If you need to add a completely new feature you can make your own component.
First check that there is no generic Nuxeo EP component available that could help you in your task (all components are not deployed in the default webapp).
Here is a quick list of the Java technology we use inside Nuxeo EP platform:
Java 5
Java EE 5: JSF and EJB3
OSGi component model
A lot a innovative open source projects
JBoss Seam, Trinidad and Ajax4JSF on the web layer
jBPM for the default workflow engine implementation
Lucene for the default search engine implementation
Jackrabbit JSR-170 repository for the default storage back end implementation
JenaRDF for the relation framework
...
Building the Nuxeo Runtime was one of the first task we started. This is one of the main infrastructure component or Nuxeo EP architecture.
This paragraph will give you a quick overview of the Nuxeo Runtime, a more detailed technical presentation can be found in an other chapter of this book.
Because most of Nuxeo EP components are shared by Nuxeo RCP (OSGI/RCP) and Nuxeo EP (Java EE), an abstraction layer is required so the components can use transparently the components services independently from the underlying infrastructure.
Nuxeo Runtime provides an abstraction layer on top of the target host platform. Depending on the target host platform, this Runtime layer may be very thin.
Nuxeo Runtime already supports Equinox (Eclipse RCP OSGi layer) and JBoss 4.x (JMX). The port of Nuxeo Runtime to other Java EE application server is in progress, we already have a part of Nuxeo EP components that can be deployed on top of SUN Glassfish application server. Technically speaking, the port of Nuxeo Runtime could be done on any JEE5 compliant platform and will be almost straightforward for any platform that supports natively the OSGi component model.
Java EE is a great standard, but it was not designed for a component based framework: it is not modular at all.
Java EE deployment model limitations
Most Java EE deployment descriptors are monolithic
For example, the web.xml descriptor is a unique XML file. If you want to deploy an additional component that needs to declare a new Java module you are stuck. You have to make one version of the web.xml for your custom configuration. For Nuxeo EP platform, this constraint is not possible:
Components don't know each other
Because there are a lot of optional components, we can't have a fixed configuration that fits all.
We can make a version of the web.xml for each possible distribution
There are too many optional components to build one static web.xml for each possible combination.
This problem with the web.xml is of course also true for a lot of standard descriptors (application.xml, faces-config.xml, persistence.xml, ejb-jar.xml ....)
One archive for one web application
We have here the exact same problem than with the web.xml. additional components can contribute new web pages, new web components ... We can have a monolithic web archive.
No dependency declaration
Inside Java EE there is no standard way to declare the dependency between components.
Because Nuxeo EP is extensible and has a plugin model, we need that feature. A contribution is dependent on the component it contribute to:
Contribution is only activated if/when the target component is activated
The contribution must be deployed after the target component as it may override some configuration
Java EE component model limitations
Unable to deploy a new component without rebuilding the whole package
If you take a .ear archive and want to add a new component, you have to rebuild a new ear.
No support for versionned components
Nuxeo Runtime provides an extensible component model that supports all these feature. It also handles the deployment of these components on the target host platform.
Nuxeo Runtime provides the component model for the platform.
This component model is heavily based on OSGi and provides the following features:
Platform agnostic component model
Can be deployed on POJO and Java EE platforms
Supports dependencies management
Components explicitly declare their requirements and are deployed and activated by respecting the inferred dependency chain.
Includes a plugin model
To let you easily configure and contribute to deployed components
A POJO test environment
Nuxeo Runtime components can be unit tested using JUnit without the need of a specific container.
OSGi ( Open Services Gateway initiative ) is a great standard for components based Java architecture.
OSGi provides out of the box the following features:
Dependencies declaration and management
A component gets activated only when the needed requirements are fulfilled
Modular deployment system
Manage bundles
Manage fragments (sub parts of a master bundle)
an OSGi bundle can define one or several services
A system to identify and lookup for a component
For Nuxeo EP, OSGi standard provides a lot of the needed features. This is the reason why Nuxeo Runtime is based on OSGi, in fact Nuxeo Runtime component model is a subset of OSGi specification.
To ensure platform transparency, Nuxeo Runtime provides adapters for each target platform to help it support OSGi components.
This adopter layer is very thin on Equinox (Eclipse RCP) since the underlying platform is already OSGi compliant.
This adapter may be more complex for platform that are not aware of OSGi (JBoss 4.x or Glassfish)
In this case, the runtime adapter will handle all OSGi logic and deploy the components as native platform components. For examples, on JBoss 4.x, Runtime components are deployed as JMX MBeans.
OSGi does not define a plugin model, but the Eclipse implementation (Equinox) does provide an extension point system.
Because we used a lot the Eclipse Extension Point system and we liked it, Nuxeo Runtime also includes an Extension Point system.
Basically every Nuxeo Component can:
declare its dependencies
The component will also be activated after all needed components
declare exposed extension points
Each components can define extension points that other components can use to contribute configuration or code.
declare contribution to other components
These declarations are handled by the OSGi deployment descriptor (MANIFEST.MF)
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Nuxeo ECM Core Bundle-SymbolicName: org.nuxeo.ecm.core;singleton:=true Bundle-Version: 1.0.0 Bundle-Vendor: Nuxeo Bundle-Localization: bundle Bundle-Activator: org.nuxeo.ecm.core.NXCoreActivator Bundle-ClassPath: ., lib/xsom.jar, lib/connector-api.jar, lib/java-cup-v11a.jar Export-Package: org.nuxeo.ecm.core, org.nuxeo.ecm.core.api, org.nuxeo.ecm.core.api.local, org.nuxeo.ecm.core.jca, org.nuxeo.ecm.core.lifecycle, org.nuxeo.ecm.core.model Require-Bundle: org.nuxeo.ecm.core.api, org.nuxeo.runtime Nuxeo-Component: OSGI-INF/CoreService.xml, OSGI-INF/TypeService.xml, OSGI-INF/RepositoryService.xml, OSGI-INF/CoreExtensions.xml, OSGI-INF/SecurityService.xml
For example, this descriptor defines that
this bundle depends on
org.nuxeo.ecm.core.api
this bundles contains Nuxeo components like
CoreServices.xml
The XML descriptor will be used to define new extension points or contribute to existing one.
An extension point is a way to declare that your component can be customized from the outside:
Contribute configuration
Activate or deactivate a component. Define resources for a given service.
Contribute code and behavior
Extension points also give you the possibility to register plugins
Extension points and contribution to extension points are defined
using a XML descriptor that has to be referenced in the
MANIFEST.MF.
Here is a simple descriptor example:
<component name="org.nuxeo.ecm.core.listener.CoreEventListenerService">
<require>org.nuxeo.ecm.core.repository.RepositoryService</require>
<implementation class="org.nuxeo.ecm.core.listener.impl.CoreEventListenerServiceImpl"/>
<extension-point name="listener">
<object class="org.nuxeo.ecm.core.listener.extensions.CoreEventListenerDescriptor"/>
</extension-point>
<extension target="org.nuxeo.ecm.core.listener.CoreEventListenerService" point="listener">
<listener name="nxruntimelistener" class="org.nuxeo.ecm.core.listener.impl.NXRuntimeEventListener" />
</extension>
<extension target="org.nuxeo.ecm.core.listener.CoreEventListenerService" point="listener">
<listener name="lifecyclelistener" class="org.nuxeo.ecm.core.lifecycle.impl.LifeCycleListener" />
</extension>
</component>
This fragment depends on the Repository Service
This fragment won't be loaded until a Nuxeo Repository is setup
This fragment declares an extension point named listener
This extension point let register plugins that will be invoked when a core event occurs.
This extension point use
CoreEventListenerDescriptor for