In progress

If you're developing an Extension to XWiki (see XWiki Architecture), you may want to save your sources under an SCM and use a build tool to transform its source into a form that can be executed inside XWiki. XWiki itself provides a Maven build and it's likely that you'll also want to use Maven to build your own Extension. This tutorial explains how to create such a build for your Extension.

Note that there are various tutorials in the Dev Guide for developing Extensions to XWiki: Java Macros, Wiki Macros, Java Components, Skin Extensions, etc. Refer to those to develop your Extension.

Your Extension falls in one of the 2 categories:

  • Extensions that are written in Java and packaged as JAR files
  • Extensions that are written in wiki pages and packaged as XAR files

Choosing Versions

Your Extension will need to depend on some XWiki modules (a.k.a Artifacts in Maven terminology), refer to the development tutorial for choosing which one are needed. However you'll also need to pick an XWiki version of those modules. Luckily, the XWiki Development Team releases all the core modules together under a single version number which corresponds to the XWiki version you see when you download XWiki.

You should know that the version you pick will have one important consequence: only versions of XWiki greater than the version you pick will be able to install your Extension. As a consequence we recommend that your Extension depend on the latest LTS version of XWiki (or older). This is the best way to ensure that the maximum number of XWiki users will be able to use your Extension while at the same time not having to support too old versions of XWiki.

Parent POM Version

In order to make your build simpler to write, we recommend that your pom.xml depend on the org.xwiki.commons:xwiki-commons-pom POM artifact, using the version of XWiki that you have chosen (see above).

Of course by doing so, you'll inherit all the best practices used by the XWiki Development Team to develop XWiki itself but that's usually a good thing emoticon_smile

One consequence though is that you'll inherit the version of Java defined for the Maven Compiler plugin:

  • Java 6 for XWiki 6.x
  • Java 7 for XWiki 7.x

Of course you can override this to use a more recent version of Java in your pom.xml (by configuring the Maven Compiler plugin) but bear in mind that if you do, all the users who are using XWiki will not be able to use your Extension since it'll require a version of Java greater than the minimal requirement for that XWiki version. For example if you build with Java 8 and you depend on XWiki 7.x then your extension will not work for users who are running XWiki under Java 7.

Beware that by depending on org.xwiki.commons:xwiki-commons-pom you'll inherit several configurations that you'll probably wish to override:

  • The XWiki project's URL: <url> tag
  • The XWiki project's groupId: <groupId> tag
  • The XWiki projet's version: <version> tag
  • The XWiki project's developers: <developers> tag
  • The XWiki project's license: <licenses> tag
  • The XWiki project's issue management tool: <issueManagement>
  • The XWiki project's mailing lists: <mailingLists>
  • The XWiki project's organization: <orgnization>
  • The XWiki project's SCM location: <scm>
  • etc.

You should also know that the Maven property commons.version will be defined and you can use it for your XWiki dependencies. We recommend to define a Maven property named xwiki.version and use it as follows:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
...
 <properties>
    ...
   <xwiki.version>${commons.version}</xwiki.version>
 </properties>
...
 <dependencies>
...
   <dependency>
     <groupId>org.xwiki.commons</groupId>
     <artifactId>xwiki-commons-component-api</artifactId>
     <version>${xwiki.version}</version>
   </dependency>
   <dependency>
     <groupId>org.xwiki.platform</groupId>
     <artifactId>xwiki-platform-oldcore</artifactId>
     <version>${xwiki.version}</version>
   </dependency>
...
 </dependencies>
...

If you wish to not depend on org.xwiki.commons:xwiki-commons-pom you could take inspiration from the Parent POM example for XWiki Contrib projects.

POM Format

The POM format is that of a typical Maven project with the addition of XWiki-specific custom Maven properties used to hold Metadata for your Extension. 

If you wish that your Extension be installable with the XWiki Distribution Wizard or the XWiki Extension Manager (the Distribution Wizard uses the Extension Manager behind the hood), you'll need to provide the following additional metadata:

  • Your Extension's name: You can provide it either in the Maven <name> tag or through a Maven property named xwiki.extension.name. If the later is defined, it's the one that will be used. This allows to provide a different name for the Maven build and for your Extension when installed.
  • (optional) Your Extension's Category, using the Maven property named <xwiki.extension.category>. Valid values are listed here. This is used to Categorize your Extension in the Extension Manager's UI.
  • (optional) Extension relocation data. If you've modified the groupId or artifactId of your Extension you need to tell it to the Extension Manager so that it can handle upgrades and understand it's the same extension being upgraded. This is achieved by using the xwiki.extension.features Maven property. For example if you previously had an Extension id of my-old-group-id:my-old-artifact-id and you're now using another id, you'd use:
    <properties>
    ...
     <!-- Old names of this module used for retro compatibility when resolving dependencies of old extensions -->
     <xwiki.extension.features>my-old-group-id:my-old-artifact-id</xwiki.extension.features>
    ...
    </properties>

Note that the Extension Manager will also read the following standard Maven POM elements:

  • <groupId> and <artifactId>: used as your Extension's id (FYI, the format is <groupId>:<artifactId>)
  • <description>: used as your Extension's description
  • <developers>: used as your Extension's developers
  • <name>: used as your Extension's name if no xwiki.extension.name property is defined

If you're interested by details, the XWiki Extension Manager gets information about your Extension by extracting it from either your JAR or your XAR (depending on whether your extension is written in Java or in wiki pages), as follows:

  • For JARs: the Maven POM that is packaged in META-INF/maven/* and the Extension Manager parses it. However since the Maven POM format doesn't contain all the information XWiki requires, XWiki defines some additional custom Maven properties.
  • For XARs: the Maven XAR plugin that XWiki provides to build a XAR generates a file in your XAR named package.xml which contains all the required metadata.

Example POM using XWiki's 6.4.6 LTS version as of this writing (adapt to the latest LTS):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
   <groupId>org.xwiki.commons</groupId>
   <artifactId>xwiki-commons-pom</artifactId>
   <version>6.4.6</version>
 </parent>
 <groupId>... your group id...</groupId>
 <artifactId>... your artifact id...</artifactId>
 <version>... your SNAPSHOT version, e.g. 1.0-SNAPSHOT...</version>
 <name>... your name...</name>
 <description>... your description...</description>
 <scm>
   <connection>... your read-only SCM id...</connection>
   <developerConnection>... your writeable SCM id...</developerConnection>
   <url>... your view URL for your SCM...</url>
 </scm>
 <developers>
   <developer>
     <id>...scm id of developer 1...</id>
     <name>... full Name of developer 1...</name>
   </developer>
    ...
   <developer>
     <id>...scm id of developer N...</id>
     <name>... full Name of developer N...</name>
   </developer>
 </developers>
 <properties>
   <!-- The Extension name. If not defined, the <name> property is used -->
   <xwiki.extension.name>... your extension's name...</xwiki.extension.name>
   <!-- The extension's category -->
   <xwiki.extension.category>... your extension's category...</xwiki.extension.category>
 </properties>
 <dependencies>
    ... dependencies required by your Extension ...
 </dependencies>
  ... other standard Maven POM configuration here (plugin configurations, etc) ...
</project>

For a Java-based Extension

In addition to the format defined above you'll need to specify the JAR <packaging> as in:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
...
 <packaging>jar</packaging>
...

For a Wiki-based Extension

In addition to the format defined above you'll need to specify the XAR <packaging>. You'll also need to register the XWiki XAR lifecycle to Maven and specify the version of the XAR plugin to use, as in:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
...
 <packaging>xar</packaging>
...
 <build>
   <!-- Needed to add support for the XAR packaging -->
   <extensions>
     <extension>
       <groupId>org.xwiki.commons</groupId>
       <artifactId>xwiki-commons-tool-xar-handlers</artifactId>
       <version>${xwiki.version}</version>
     </extension>
   </extensions>
   <plugins>
     <!-- The XAR packaging uses the XAR plugin and thus we need to define what version to use -->
     <plugin>
       <groupId>org.xwiki.commons</groupId>
       <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
       <version>${xwiki.version}</version>
     </plugin>
      ...
   </plugins>
    ...
 </build>
...

Building your Extension

Make sure that you've configured Maven to use XWiki's Remote Repository as otherwise Maven will not find your declared XWiki dependencies.

To build your Extension, execute mvn clean install

If your Extension is a XAR one, you can also run mvn xar:format to let the Maven XAR plugin perform some formatting on the XML files representing your wiki pages.

Deploying your Extension

Now that you've built your Extension you have a XAR or JAR and you need to install it inside XWiki. You have several options for doing so.

As a Core Extension

If your Extension is a JAR you can deploy it by copying it to your Servlet container's WEB-INF/lib directory along with all its dependencies (excluding the XWiki dependencies that are already present in WEB-INF/lib). This is not the easiest way and you'll need to restart XWiki for the Extension to be loaded. Your Extension will be recognized as a Core Extension by the Extension Manager and as a consequence it'll be available globally for all the subwikis in your XWiki instance.

As a XAR Import

If your Extension is a XAR you can go to the Wiki Administration UI and Import it. The XWiki Importer will recognize that its an Extension (through the generated package.xml file, see above) and will install it as an Extension available for all the subwikis in your XWiki instance.

Using a Local Extension Repository

After you've built your Extension using Maven, the generated artifact is available in your local Maven Repository and you could configure your XWiki instance to recognize this local Maven Repository as an Extension Repository. To do this, edit XWiki's WEB-INF/xwiki.properties file and uncomment the following lines (the first line is the important one but since you're overriding the default configuration you'll also need to have the following 2 lines which are the default you get when you don't configure repositories explicitly):

extension.repositories=local:maven:file://${userHome}/.m2/repository
extension.repositories=maven-xwiki:maven:http://nexus.xwiki.org/nexus/content/groups/public
extension.repositories=extensions.xwiki.org:xwiki:http://extensions.xwiki.org/xwiki/rest/

Once this is done you can install your Extension through the Extension Manager's UI by clicking "Advanced Search" and entering your Extension's id and version. Note that the reason you cannot using the Search feature of the Extension Manager is because a Maven Repository is not a searchable Extension repository (Maven doesn't offer a search feature by default).

Using extensions.xwiki.org

Last but not least, you could deploy your Extension on the xwiki.org Extensions wiki so that it's available by default to everyone in the world using XWiki! If your extension is not meant to be private this is obviously the recommended approach.

To do so, register on xwiki.org and Contribute an extension on extensions.xwiki.org.

Note that you also have the possibility to share your extension with the rest of the XWiki community by making it a XWiki Contrib project. If you do so, the XWiki project offers a streamlined solution for deploying easily your extension onto extensions.xwiki.org (in addition to offering several other tools, such as an issue tracker, a CI, and more).

Need Help?

If you still need help writing and deploying your XWiki Extension, contact the XWiki Support.

Tags:
Created by Vincent Massol on 2015/12/12 14:32
   

Get Connected