Publish JavaDoc API Documentation when Releasing from Jenkins

By | December 26, 2013
Reading Time: 7 minutes

This article describes how to publish JavaDoc API documentation for a Maven project built on Jenkins when that project is released. The JavaDoc API documentation is published using the same instance of Apache Tomcat 7 that Jenkins runs on.

Motivation

I wanted to, using the simplest way possible, publish JavaDoc API documentation for releases of a certain software component and make it available at a URL unique to each version. In addition, I wanted to make the possible to list the different versions of the software component for which documentation is available.
The software component is built using Maven and releases are made from a Jenkins server.

Required Jenkins Plug-ins

The following plug-ins need to be installed in Jenkins in order to be able to complete the example in this article:

  • The appropriate plug-in for the source code management system you use.
    In this article I will use Git, but any other source code management system works equally well as long as there is a Jenkins plug-in available for it.
  • Maven Project Plug-in.
    Enables the creation of Maven 2/3 jobs in Jenkins.
  • Jenkins M2 Release Plug-in
    Also know as the Maven Release Plug-in, which enables the performing of Maven releases from a Jenkins job.

Prepare Apache Tomcat

The following steps prepares a special web application, the documentation web application, in Apache Tomcat 7 to which JavaDoc API documentation will be published. It is assumed that the directory containing the web applications deployed to Tomcat resides in the webapps directory in the Tomcat installation directory.

  • In the webapps directory in the Tomcat home directory, create a directory for the documentation web application.
    In this example, I name my directory “api-documentation”, but you are of course free to choose any name you find appropriate.
  • In the documentation web application directory, create a WEB-INF directory.
  • In the WEB-INF directory created in the previous step, create a file named “web.xml”.
    The resulting directory structure should look like in the following picture:

Tomcat Directory Structure

  • Paste the following into the web.xml file created in the previous step:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
    Configures the default servlet to allow directory listings for the
    documentation web application.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--
        Start of security configuration.
        This section can be removed if no security is required for API documentation.
    -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>API Documentation Root</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <!--
                This role must be present in the tomcat-users.xml file.
                The username and password to enter when accessing API documentation is the
                username and password of any user belonging to this role.
            -->
            <role-name>manager-gui</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>API Documentation</realm-name>
    </login-config>

    <security-role>
        <description>The role that is required to access the API Documentation</description>
        <!--
            This role must be present in the tomcat-users.xml file.
            The username and password to enter when accessing API documentation is the
            username and password of any user belonging to this role.
        -->
        <role-name>manager-gui</role-name>
    </security-role>
    <!-- End of security configuration. -->
</web-app>

The above web application configuration file configures the Tomcat default servlet to allow directory listings. Since the configuration file is located in a specific web application, directory listings will only be allowed in that particular web application.
In addition, security is configured, requiring login before being able to view API documentation. Note that the role specified in the element must be defined in the tomcat-users.xml file. Removing the indicated security configuration section removes security constraints for API documentation.

Please refer to the web.xml file in the conf directory in the Apache Tomcat 7 directory for information on the different configuration alternatives available for the default servlet.

Configure the Maven Project

Assuming that the software component for which I want to publish JavaDoc API documentation for already is a Maven project, I still need to ensure the following:

  • JavaDoc API documentation is created for the software component.
  • The JavaDoc API documentation is created at the correct location to allow for deployment by the Maven site plug-in.
    That is, I want the documentation to be located in the site directory in the target directory of the Maven project, not directly under the target directory of the project.
  • Documentation is not published in by every build.
    Since I only want to preserve documentation for release builds, I need to be able to control when documentation is published.
  • Documentation is published to the appropriate location.
    I expect that I want to publish JavaDoc API documentation for multiple software components in the future. I also want to be able to publish documentation for different versions of a software component.

The following Maven pom.xml file contains configuration to create and publish JavaDoc. Parts not relevant to the creation of documentation have been omitted.

<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/xsd/maven-4.0.0.xsd">

    ...

    <!--
        Determines to which repository releases of the project are deployed.
        In this example, artifacts are deployed to a directory on the
        same computer on which the Jenkins build server is run.
        Note that this is just the minimal configuration required in order
        to be able to perform a Maven release, not recommended for production.
        Reference: http://maven.apache.org/pom.html#Distribution_Management
    -->
    <distributionManagement>
        <repository>
            <uniqueVersion>false</uniqueVersion>
            <id>home1</id>
            <name>Home Repository</name>
            <url>file://C:/MyProjectDeployDirectory/</url>
            <layout>default</layout>
        </repository>
    </distributionManagement>

    <!--
        SCM configuration is necessary in order to enable Maven to manage
        the version of the project when releasing a new version on the
        Jenkins build server.
        The configuration varies depending on which provider is used
        (for example, Git, Subversion, etc).
        In this example, Git is used.
        Reference: http://maven.apache.org/pom.html#SCM
    -->
    <scm>
       <connection>scm:git:file://localhost/C:/GitRepo/MyProject/</connection>
       <developerConnection>scm:git:file://localhost/C:/GitRepo/MyProject/</developerConnection>
       <tag>HEAD</tag>
    </scm>

    <properties>
        <!--
            Path to the root directory of the documentation web application.
            This example assumes that the documentation web application
            is located in the same Tomcat instance as the Jenkins build
            server runs.
        -->
        <release.javadoc.root.path>[path to Tomcat home]/webapps/api-documentation/</release.javadoc.root.path>
        
        ...
    </properties>

    ...

    <profiles>
        <!--
            Profile for generation and publishing of release JavaDoc
            documentation.
            Use: mvn -P releaseDocumentation site
            References: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
        -->
        <profile>
            <!-- 
                Name of the Maven build profile.
                Used in project's Jenkins job configuration.
            -->
            <id>releaseDocumentation</id>
            <build>
                <plugins>
                    <!--
                        In preparation of site generation, extract the release
                        version number to a maven property.
                        Performed during pre-site phase.
                    -->
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>build-helper-maven-plugin</artifactId>
                        <version>1.8</version>
                        <executions>
                            <execution>
                                <phase>pre-site</phase>
                                <id>regex-property</id>
                                <goals>
                                    <goal>regex-property</goal>
                                </goals>
                                <configuration>
                                    <name>release_version</name>
                                    <value>${project.version}</value>
                                    <regex>-SNAPSHOT</regex>
                                    <replacement />
                                    <failIfNoMatch>false</failIfNoMatch>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!--
                        JavaDoc generation.
                        JavaDoc is generated during pre-site phase.
                    -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>2.9.1</version>
                        <executions>
                            <execution>
                                <phase>pre-site</phase>
                                <goals>
                                    <goal>javadoc</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <show>private</show>
                        </configuration>
                    </plugin>
                    <!--
                        Copy JavaDoc to publish directory.
                        Performed during the site phase.
                        If changing the phase, make sure that copying the
                        documentation is performed after having generated
                        the JavaDoc.
                    -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-resources-plugin</artifactId>
                        <version>2.6</version>
                        <executions>
                            <execution>
                                <id>copy-resources</id>
                                <phase>site</phase>
                                <goals>
                                    <goal>copy-resources</goal>
                                </goals>
                                <configuration>
                                    <generateProjectInfo>false</generateProjectInfo>
                                    <generateReports>false</generateReports>
                                    <outputDirectory>${release.javadoc.root.path}${project.artifactId}-${release_version}/</outputDirectory>
                                    <resources>
                                        <resource>
                                            <directory>${project.build.directory}/site/</directory>
                                            <filtering>true</filtering>
                                        </resource>
                                    </resources>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <!--
                Include this section to disable, or configure, generation
                of project info report(s).
                In this case, all project info reports have been disabled.
            -->
            <reporting>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-project-info-reports-plugin</artifactId>
                        <version>2.7</version>
                        <reportSets>
                            <reportSet>
                                <reports>
                                </reports>
                            </reportSet>
                        </reportSets>
                    </plugin>
                </plugins>
            </reporting>
        </profile>
    </profiles>
</project>

Note that:

  • The element is required, in order for Maven to know to which repository to deploy project artifacts when performing a release.
    This example shows a minimal configuration, using a local directory as target, which is not recommended for production.
  • It is not possible to use the element to specify where to publish the documentation, since this configuration is evaluated before we are able to set Maven properties using the Maven build helper plug-in.
  • The element specifies where the project is located in the source-code management system.
    This configuration is necessary, in order for Maven to be able to update the project version number when performing a release. This configuration depends on the source-code management system used (example: Subversion, Git, Perforce etc).
    In this example, the Git source-code management system is used with the Git repository residing in a local directory.
  • In the <properties> element, a Maven property named “release.javadoc.root.path” is defined.
    This property specifies the local directory to which release JavaDoc documentation will be copied. The string “[path to Tomcat home]” needs to be replaced with the path to the Tomcat installation directory, or the directory that contains the webapps directory used by Tomcat if it is not present in the Tomcat directory.
  • In the <profiles> element, a Maven build profile named “releaseDocumentation” is defined.
    This is the Maven build profile that determines what happens when release JavaDoc documentation is to be produced and published.
  • The first plug-in in this profile is the Maven build helper plug-in.
    It is used to remove the “-SNAPHOT” part of the version number of the software component and store the result in the Maven property “release_version”.
    It is difficult to intercept the workings of the Maven release plug-in at a stage where the release version number is available, so this strategy was chosen to keep the Maven configuration simpler.
  • The Maven build helper plug-in is configured to execute during the Maven pre-site phase.
    This in order to be part of the Maven site goal which we will use to create and publish the JavaDoc documentation.
  • The Maven JavaDoc plug-in is used to generate the JavaDoc.
    No surprise here, except that the execution phase is set to pre-site. As with the Maven build helper plug-in, in order to be part of the Maven site goal which we will use to create and publish the JavaDoc documentation.
  • The Maven resources plug-in is used to copy (publish) the JavaDoc documentation to the api-documentation web application in Tomcat.
    This plug-in will execute during the Maven site phase. The site phase executes after the pre-site phase and this ensures that the JavaDoc has been created and that the Maven “release_version” property has been set.

To generate and publish JavaDoc documentation for the software component, we can now issue the following command:

mvn -P releaseDocumentation site

Configure the Jenkins Job

To generate and publish documentation as part of a Maven release performed in Jenkins, we need to include the above Maven property and goal in the release goals of the Jenkins job for the software component.
In my case the Build Environment section of the job configuration looks like this:

Jenkins Job ConfigurationRemember to save the job configuration after you have made the changes!

View Project JavaDoc

Now when I perform a Maven release from Jenkins, the documentation is published and I can browse the documentation available for the different software components and their different versions by opening the URL http://localhost:8080/api-documentation/ in my browser and then drill down into the appropriate directory.

On the first page you will see a list of the projects and versions for which JavaDoc have been published:

API Documentation Root

Click the link for the project and version which JavaDoc you want to view. In my example I click the link for version 1.0.5 of the JMSRequestReply project:

API Documentation Project

Click the “apidocs” link to view the JavaDoc.

Leave a Reply

Your email address will not be published. Required fields are marked *