<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN" "http://docbook.org/xml/5.0/dtd/docbook.dtd">
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements. See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership. The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License. You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied. See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
  -->
<book>
    <info>
        <title>Axiom Developer Guide</title>
        <releaseinfo>&version;</releaseinfo>

        <legalnotice>
            <para>
                Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See
                the NOTICE file distributed with this work for additional information regarding copyright ownership. The
                ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use
                this file except in compliance with the License. You may obtain a copy of the License at
            </para>
            <para>
                <link xlink:href="http://www.apache.org/licenses/LICENSE-2.0"/>
            </para>
            <para>
                Unless required by applicable law or agreed to in writing, software distributed under the License is
                distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
                implied. See the License for the specific language governing permissions and limitations under the
                License.
            </para>
        </legalnotice>
    </info>

    <toc/>

    <chapter>
        <title>Working with the Axiom source code</title>
        <section>
            <title>Importing the Axiom source code into Eclipse</title>
            <para>
                Use the following steps to import the Axiom source code into Eclipse Photon (4.8.0):
            </para>
            <procedure>
                <step>
                    <para>
                        Install AJDT using the following update site:
                    </para>
                    <para>
                        <link xlink:href="http://download.eclipse.org/tools/ajdt/48/dev/update"/>
                    </para>
                    <para>
                        Only the "AspectJ Development Tools" feature is required.
                    </para>
                </step>
                <step>
                    <para>
                        Install Workspace Mechanic using the following update site:
                    </para>
                    <para>
                        <link xlink:href="https://alfsch.github.io/eclipse-updates/workspacemechanic"/>
                    </para>
                </step>
                <step>
                    <para>
                        Import the Axiom sources as "Existing Maven Projects" into a new Eclipse workspace. M2Eclipse will
                        propose to install additional Maven plugin connectors; make sure that you install them all.
                    </para>
                </step>
                <step>
                    <para>
                        Configure Workspace Mechanic using the files under <filename>etc/workspacemechanic</filename> and
                        accept the proposed preference changes.
                    </para>
                </step>
            </procedure>
        </section>
        <section>
            <title>Testing</title>
            <section>
                <title>Unit test organization</title>
                <para>
                    Historically, all unit tests were placed in the <filename>axiom-tests</filename> project.
                    One specific problem with this is that since all tests are in a common Maven module
                    which depends on both <filename>axiom-impl</filename> and <filename>axiom-dom</filename>,
                    it is not rare to see DOOM tests that accidentally use the LLOM implementation (which is the default).
                    The project description in <filename>axiom-tests/pom.xml</filename> indicates that it
                    was the intention to split the <filename>axiom-tests</filename> project into several parts
                    and make them part of <filename>axiom-api</filename>, <filename>axiom-impl</filename> and
                    <filename>axiom-dom</filename>. This reorganization is not complete
                    yet<footnote><para>See <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-311">AXIOM-311</link>.</para></footnote>.
                    For new test cases (or when refactoring existing tests), the following guidelines should be applied:
                </para>
                <orderedlist>
                    <listitem>
                        <para>
                            Tests that validate the code in <filename>axiom-api</filename> and that do not require
                            an Axiom implementation to execute should be placed in <filename>axiom-api</filename>.
                            This primarily applies to tests that validate utility classes in <filename>axiom-api</filename>.
                        </para>
                    </listitem>
                    <listitem xml:id="test.category.api">
                        <para>
                            The code of unit tests that apply to all Axiom implementations and that check conformance
                            to the specifications of the Axiom API should be added
                            to <filename>axiom-api</filename> and executed in <filename>axiom-impl</filename> and
                            <filename>axiom-dom</filename>. Currently, the recommended way is to create a
                            base class in <filename>axiom-api</filename> (with suffix <classname>TestBase</classname>) and
                            to create subclasses in <filename>axiom-impl</filename> and <filename>axiom-dom</filename>.
                            This makes sure that the DOOM tests never accidentally use LLOM (because
                            <filename>axiom-impl</filename> is not a dependency of <filename>axiom-dom</filename>).
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            Tests that check integration with other libraries should be placed in
                            <filename>axiom-integration</filename>. Note that this is the only module that requires
                            Java 1.5 (so that e.g. integration with JAXB2 can be tested).
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            Tests related to code in <filename>axiom-api</filename> and requiring an Axiom
                            implementation to execute, but that don't fall into category <xref linkend="test.category.api"/>
                            should stay in <filename>axiom-tests</filename>.
                        </para>
                    </listitem>
                </orderedlist>
            </section>
            <section>
                <title>Testing Axiom with different StAX implementations</title>
                <para>
                    The following StAX implementations are available to test compatibility with Axiom:
                </para>
                <variablelist>
                    <?dbfo list-presentation="blocks"?>
                    <varlistentry>
                        <term>Woodstox</term>
                        <listitem>
                            <para>
                                This is the StAX implementation that Axiom uses by default.
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>Sun Java Streaming XML Parser (SJSXP)</term>
                        <listitem>
                            <para>
                                This implementation is available as Maven artifact <literal>com.sun.xml.stream:sjsxp:1.0.1</literal>.
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>StAX Reference Implementation</term>
                        <listitem>
                            <para>
                                The reference implementation was written by BEA and is available as Maven artifact
                                <literal>stax:stax:1.2.0</literal>. The homepage is <link xlink:href="http://stax.codehaus.org/Home"/>.
                                Note that the JAR doesn't contain the necessary files to enable service discovery.
                                Geronimo's implementation of the StAX API library will not be able to locate
                                the reference implementation unless the following system properties are set:
                            </para>
<programlisting><?db-font-size 80%?>javax.xml.stream.XMLInputFactory=com.bea.xml.stream.MXParserFactory
javax.xml.stream.XMLOutputFactory=com.bea.xml.stream.XMLOutputFactoryBase</programlisting>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>XL XP-J</term>
                        <listitem>
                            <para>
                                <quote>XL XML Processor for Java</quote> is IBM's implementation of StAX 1.0
                                and is part of IBM's JRE/JDK v6. Note that due
                                to an agreement between IBM and Sun, IBM's Java implementation for the Windows
                                platform is not available as a separate download, but only bundled with another
                                IBM product, e.g. <link xlink:href="http://www.ibm.com/developerworks/downloads/ws/wasdevelopers/">WebSphere
                                Application Server for Developers</link>.
                            </para>
                            <para>    
                                On the other hand, the JDK for Linux can be downloaded as a separate package from the
                                <link xlink:href="https://www.ibm.com/developerworks/java/jdk/linux/download.html">developerWorks
                                site</link>. There are versions for 32-bit x86 (<quote>xSeries</quote>) and 64-bit AMD.
                                They are available as RPMs and tarballs. To install the JDK properly on a Debian
                                based system (including Ubuntu), follow the instructions given in
                                <xref linkend="install.ibm.jdk"/>.
                            </para>
                        </listitem>
                    </varlistentry>
                </variablelist>
            </section>
        </section>
    </chapter>
    
    <chapter>
        <title>Design</title>
        <section>
            <title>General design principles and goals</title>
            <formalpara>
                <title>Consistent serialization</title>
                <para>
                    Axiom supports multiple methods and APIs to serialize an object model to XML or to transform it
                    to another (non Axiom) representation. This includes serialization to byte or character streams, transformation
                    to StAX in push mode (i.e. writing to an <classname>XMLStreamWriter</classname>) or pull mode
                    (i.e. reading from an <classname>XMLStreamReader</classname>), as well as transformation to SAX.
                    The representations produced by these different methods should be consistent with each other.
                    If a given use case can be implemented using more than one of these methods, then the end result
                    should be the same, whichever method is chosen.
                </para>
            </formalpara>
            <para>
                <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-430">AXIOM-430</link> provides an example
                where this principle was not respected.
            </para>
            <para>
                It should be noted that this principle can obviously only be respected within the limits imposed
                by a given API. E.g. if a given API has limited support for DTDs, then a <tag class="element">DOCTYPE</tag>
                declaration may be skipped when that API is used.
            </para>
        </section>
    
        <section>
            <title><classname>LifecycleManager</classname> design (Axiom 1.3)</title>
            <para>
                The <classname>LifecycleManager</classname> API is used by the MIME handling code in Axiom
                to manage the temporary files that are used to buffer the content of attachment parts.
                The <classname>LifecycleManager</classname> implementation is responsible to track the temorary
                files that have been created and to ensure that they are deleted when they are no longer used.
                In Axiom 1.2.x, this API has multiple issues and a redesign is required for Axiom 1.3.
            </para>
            <section>
                <title>Issues with the <classname>LifecycleManager</classname> API in Axiom 1.2.x</title>
                <orderedlist>
                    <listitem>
                        <para>
                            Temporary files that are not cleaned up explicitly by application code will only be removed
                            when the JVM stops (<classname>LifecycleManagerImpl</classname> registers a shutdown hook
                            and maintains a list of files that need to be deleted when the JVM exits). This means that
                            temporary files may pile up, causing the file system to fill.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <classname>LifecycleManager</classname> also has a method <methodname>deleteOnTimeInterval</methodname>
                            that deletes a file after some specified time interval. However, the implementation creates a new
                            thread for each invocation of that method, which is generally not acceptable in high performance
                            use cases.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            One of the stated design goals (see <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-192">AXIOM-192</link>)
                            of the <classname>LifecycleManager</classname> API was to wrap the files in <classname>FileAccessor</classname> objects to
                            <quote>keep track of activity that occurs on the files</quote>. However, as pointed out in
                            <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-185">AXIOM-185</link>, since
                            <classname>FileAccessor</classname> has a method that returns the corresponding <classname>File</classname>
                            object, this goal has not been reached.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            As noted in <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-382">AXIOM-382</link>, the fact
                            that <classname>LifecycleManagerImpl</classname> registers a shutdown hook which is never unregistered
                            causes a class loader leak in J2EE environments.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            In an attempt to work around the issues related to <classname>LifecycleManager</classname> (in particular
                            the first item above), <link xlink:href="https://issues.apache.org/jira/browse/AXIOM-185">AXIOM-185</link>
                            introduced another class called <classname>AttachmentCacheMonitor</classname> that implements a timer
                            based mechanism to clean up temporary files. However, this change causes other issues:
                        </para>
                        <itemizedlist>
                            <listitem>
                                <para>
                                    The existence of this API has a negative impact on Axiom's architectural integrity because it
                                    has functionality that overlaps with <classname>LifecycleManager</classname>. This means that
                                    we now have two completely separate APIs that are expected to serve the same purpose, but
                                    none of them addresses the problem properly.
                                </para>
                            </listitem>
                            <listitem>
                                <para>
                                    <classname>AttachmentCacheMonitor</classname> automatically creates a timer, but there is no
                                    way to stop that timer. This means that this API can only be used if Axiom is integrated
                                    into the container, but not when it is deployed with an application.
                                </para>
                            </listitem>
                        </itemizedlist>
                        <para>
                            Fortunately, that change was only meant as a workaround to solve a particular issue in WebSphere
                            (see APAR <link xlink:href="http://www-01.ibm.com/support/docview.wss?rs=180&amp;uid=swg1PK91497">PK91497</link>),
                            and once the <classname>LifecycleManager</classname> API is redesigned to solve that issue,
                            <classname>AttachmentCacheMonitor</classname> no longer has a reason to exist.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <classname>LifecycleManager</classname> is an abstract API (interface), but refers to
                            <classname>FileAccessor</classname> which is placed in an <literal>impl</literal> package.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <classname>FileAccessor</classname> uses the <classname>MessagingException</classname> class
                            from JavaMail, although Axiom no longer relies on this API to parse or create MIME messages.
                        </para>
                    </listitem>
                </orderedlist>
            </section>
            <section>
                <title>Cleanup strategy for temporary files</title>
                <para>
                    As pointed out in the previous section, one of the primary problems with the
                    <classname>LifecycleManager</classname> API in Axiom 1.2.x is that temporary files that are
                    not cleaned up explicitly by application code (e.g. using the <methodname>purgeDataSource</methodname> method
                    defined by <classname>DataHandlerExt</classname>) are only removed when the JVM exits.
                    A timer based strategy that deletes temporary file after a given time interval (as proposed
                    by <classname>AttachmentCacheMonitor</classname>) is not reliable
                    because in some use cases, application code may keep a reference to the attachment part for
                    a long time before accessing it again.
                </para>
                <para>
                    The only reliable strategy is to take advantage of finalization, i.e. to rely on the garbage
                    collector to trigger the deletion of temporary files that are no longer used. For this to work
                    the design of the API (and its default implementation) must satisfy the following two conditions:
                </para>
                <orderedlist>
                    <listitem>
                        <para>
                            All access to the underlying file must be strictly encapsulated, so that the file
                            is only accessible as long as there is a strong reference to the object that
                            encapsulates the file access. This is necessary to ensure that the file can
                            be safely deleted once there is no longer a strong reference and the
                            object is garbage collected.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            Java guarantees that the finalizer is invoked before the instance is garbage
                            collected. However, instances are not necessarily garbage collected before the
                            JVM exits, and in that case the finalizer is never invoked. Therefore, the
                            implementation must delete all existing temporary files when the JVM exits.
                            The API design should also take into account that some implementations of
                            the <classname>LifecycleManager</classname> API may want to trigger this
                            cleanup before the JVM exits, e.g. when the J2EE application in which
                            Axiom is deployed is stopped.
                        </para>
                    </listitem>
                </orderedlist>
                <para>
                    The first condition can be satisfied by redesigning the <classname>FileAccessor</classname>
                    such that it never leaks the name of the file it represents (neither as a <classname>String</classname>
                    nor a <classname>File</classname> object). This in turn means that the
                    <classname>CachedFileDataSource</classname> class must be removed from the Axiom API.
                    In addition, the <methodname>getInputStream</methodname> method defined by
                    <classname>FileAccessor</classname> must no longer return a simple <classname>FileInputStream</classname>
                    instance, but must use a wrapper that keeps a strong reference to the <classname>FileAccessor</classname>,
                    so that the <classname>FileAccessor</classname> can't be garbage collected while the
                    input stream is still in use.
                </para>
                <para>
                    To satisfy the second condition, one may want to use <methodname>File#deleteOnExit</methodname>.
                    However, this method causes a native memory leak, especially when used with temporary files,
                    which are expected to have unique names (see
                    <link xlink:href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4513817">bug 4513817</link>).
                    Therefore this can only be implemented using a shutdown hook. However, a shutdown hook will
                    cause a class loader leak if it is used improperly, e.g. if it is registered by an application deployed
                    into a J2EE container and not unregistered when that application is stopped. For this
                    particular case, it is possible to create a special <classname>LifecycleManager</classname>
                    implementation, but for this to work, the lifecycle of this type of <classname>LifecycleManager</classname>
                    must be bound to the lifecycle of the application, e.g. using a
                    <classname>ServletContextListener</classname>. This is not always possible and this approach
                    is therefore not suitable for the default <classname>LifecycleManager</classname> implementation.
                </para>
                <para>
                    To avoid the class loader leak, the default <classname>LifecycleManager</classname> implementation
                    should register the shutdown hook when the first temporary file is registered and
                    automatically unregister the shutdown hook again when there are no more temporary files.
                    This implies that the shutdown hook is repeatedly registered and unregistered. However, since
                    these are relatively cheap operations<footnote><para>Since the JRE typically uses an
                    <classname>IdentityHashMap</classname> to store shutdown hooks, the only overhead is caused
                    by Java 2 security checks and synchronization.</para></footnote>, this should not be a concern.
                </para>
                <para>
                    An additional complication is that when the shutdown hook is executed, the temporary files
                    may still be in use. This contrasts with the finalizer case where encapsulation guarantees
                    that the file is no longer in use. This situation doesn't cause an issue on Unix platforms (where it is possible
                    to delete a file while it is still open), but needs to be handled properly on Windows.
                    This can only be achieved if the <classname>FileAccessor</classname> keeps track of
                    created streams, so that it can forcibly close the underlying <classname>FileInputStream</classname> objects.
                </para>
            </section>
        </section>
    </chapter>
    
    <chapter>
        <title>Release process</title>
        <section>
            <title>Release preparation</title>
            <para>
                The following items should be checked before starting the release process:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        Check that the generated Javadoc contains the appropriate set of packages, i.e. only the public API.
                        This excludes classes from <filename>axiom-impl</filename> and <filename>axiom-dom</filename> as well as classes
                        related to unit tests.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Check that all dependencies and plugins are available from standard
                        repositories. To do this, clean the local repository and execute
                        <command>mvn clean install</command> followed by <command>mvn site</command>.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Check that the set of license files in the <filename>legal</filename> directory
                        is complete and accurate (by checking that in the binary distribution, there is a license file
                        for every third party JAR in the <filename>lib</filename> folder).
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Check that the Maven site conforms to the latest version of the
                        <link xlink:href="http://apache.org/foundation/marks/pmcs">Apache Project
                        Branding Guidelines</link>.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Check that the <literal>apache-release</literal> profile can be executed properly.
                        To do this, issue the following command:
                    </para>
                    <screen>mvn clean install -Papache-release -DskipTests=true</screen>
                    <para>
                        You may also execute a dry run of the release process:
                    </para>
                    <screen>mvn release:prepare -DdryRun=true</screen>
                    <para>
                        After this, you need to clean up using the following command:
                    </para>
                    <screen>mvn release:clean</screen>
                </listitem>
                <listitem>
                    <para>
                        Check that the Maven site can be generated and deployed successfully, and that it has
                        the expected content.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Complete the release note (<filename>src/site/markdown/release-notes/<replaceable>version</replaceable>.md</filename>).
                        It should include a description of the major
                        changes in the release as well as a list of resolved JIRA issues.
                    </para>
                </listitem>
            </itemizedlist>
        </section>
        <section>
            <title>Prerequisites</title>
            <para>
                The following things are required to perform the actual release:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        A PGP key that conforms to the <link xlink:href="http://www.apache.org/dev/release-signing.html">requirement
                        for Apache release signing</link>. To make the release process easier, the passphrase for the
                        code signing key should be configured in <filename>${user.home}/.m2/settings.xml</filename>:
                    </para>
<screen><![CDATA[<settings>
  ...
  <profiles>
    <profile>
      <id>apache-release</id>
      <properties>
        <gpg.passphrase><!-- KEY PASSPHRASE --></gpg.passphrase>
      </properties>
    </profile>
  </profiles>
  ...
</settings>]]></screen>
                </listitem>
                <listitem>
                    <para>
                        The release process uses a Nexus staging repository. Every committer should have access to the corresponding
                        staging profile in Nexus. To validate this, login to <literal>repository.apache.org</literal> and check that
                        you can see the <literal>org.apache.ws</literal> staging profile. The credentials used to deploy to Nexus
                        should be added to <filename>settings.xml</filename>:                    
                    </para>
<screen><![CDATA[<servers>
  ...
  <server>
    <id>apache.releases.https</id>
    <username><!-- ASF username --></username>
    <password><!-- ASF LDAP password --></password>
  </server>
  ...
</servers>]]></screen>
                </listitem>
            </itemizedlist>
        </section>
        <section>
            <title>Release</title>
            <para>
                In order to prepare the release artifacts for vote, execute the following steps:
            </para>
            <procedure>
                <step>
                    <para>
                        If necessary, update the copyright date in the top level <filename>NOTICE</filename> file.
                    </para>
                </step>
                <step>
                    <para>
                        Start the release process with the following command:
                    </para>
                    <screen>mvn release:prepare</screen>
                    <para>
                        When asked for the "SCM release tag or label", keep the default value
                        (<literal>x.y.z</literal>).
                    </para>
                    <para>
                        The above command will create a tag in Subversion and increment the version
                        number of the trunk to the next development version. It will also create
                        a <filename>release.properties</filename> file that will be used in the next step.
                    </para>
                </step>
                <step>
                    <para>
                        Perform the release using the following command:
                    </para>
                    <screen>mvn release:perform</screen>
                    <para>
                        This will upload the release artifacts to the Nexus staging repository.
                    </para>
                </step>
                <step>
                    <para>
                        Log in to the Nexus repository (<link xlink:href="https://repository.apache.org/"/>
                        and close the staging repository. The name of the staging profile is
                        <literal>org.apache.ws</literal>. See <link xlink:href="https://maven.apache.org/developers/release/maven-project-release-procedure.html"/>
                        for a more thorough description of this step.
                    </para>
                </step>
                <step>
                    <para>
                        Execute the <filename>target/checkout/etc/dist.py</filename> script to upload the source and binary distributions to
                        the development area of the <link xlink:href="https://dist.apache.org/repos/dist/"/> repository.
                    </para>
                    <para>
                        If not yet done, export your public key and append it to <link xlink:href="https://dist.apache.org/repos/dist/release/ws/axiom/KEYS"/>.
                        The command to export a public key is as follows:
                    </para>
                    <screen>gpg --armor --export <replaceable>key_id</replaceable></screen>
                </step>
                <step>
                    <para>
                        Delete <link xlink:href="https://svn.apache.org/repos/asf/webservices/website/axiom-staging/"/> if it exists.
                        Create a new staging area for the site:
                    </para>
<screen>svn copy \
 https://svn.apache.org/repos/asf/webservices/website/axiom \
 https://svn.apache.org/repos/asf/webservices/website/axiom-staging</screen>
                    <tip>
                        <para>
                            This step can be skipped if the staging area has already been created earlier (e.g. to test a snapshot version of the site).
                        </para>
                    </tip>
                </step>
                <step>
                    <para>
                        Change to the <filename>target/checkout</filename> directory and prepare the site using the following commands:
                    </para>
<screen>mvn site-deploy
mvn scm-publish:publish-scm -Dscmpublish.skipCheckin=true</screen>
                    <para>
                        The staging area will be checked out to <filename>target/scmpublish-checkout</filename> (relative to
                        <filename>target/checkout</filename>). Do a sanity check on the changes and then commit them.
                    </para>
                </step>
                <step>
                    <para>
                        Start the release vote by sending a mail to <literal>dev@ws.apache.org</literal>.
                        The mail should mention the following things:
                    </para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                The list of issues solved in the release (by linking to the relevant
                                JIRA view).
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                The location of the Nexus staging repository.
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                The link to the source and binary distributions:
                                <literal>https://dist.apache.org/repos/dist/dev/ws/axiom/<replaceable>version</replaceable></literal>.
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                A link to the preview of the Maven site: <link xlink:href="http://ws.apache.org/axiom-staging/"/>.
                            </para>
                        </listitem>
                    </itemizedlist>
                </step>
            </procedure>
            <para>
                If the vote passes, execute the following steps:
            </para>
            <procedure>
                <step>
                    <para>
                        Promote the artifacts in the staging repository. See
                        <link xlink:href="http://maven.apache.org/developers/release/apache-release.html"/>
                        for detailed instructions for this step.
                    </para>
                </step>
                <step>
                    <para>
                        Publish the distributions:
                    </para>
<screen>svn mv https://dist.apache.org/repos/dist/dev/ws/axiom/<replaceable>version</replaceable> \
       https://dist.apache.org/repos/dist/release/ws/axiom/</screen>
                    <para>
                        <replaceable>version</replaceable> is the release version, e.g. <literal>1.2.9</literal>.
                    </para>
                </step>
                <step>
                    <para>
                        Publish the site:
                    </para>
<screen>svn co --depth=immediates https://svn.apache.org/repos/asf/webservices/website ws-site
cd ws-site
svn rm axiom
svn mv axiom-staging axiom
svn commit</screen>
                </step>
            </procedure>
            <para>
                It may take several hours before all the updates have been synchronized to the relevant
                ASF systems. Before proceeding, check that
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        the Maven artifacts for the release are available from the Maven central repository;
                    </para>
                </listitem>
                <listitem>
                    <para>
                        the Maven site has been synchronized to <link xlink:href="http://ws.apache.org/axiom/"/>;
                    </para>
                </listitem>
                <listitem>
                    <para>
                        the binary and source distributions can be downloaded from <link xlink:href="http://ws.apache.org/axiom/download.html"/>.
                    </para>
                </listitem>
            </itemizedlist>
            <para>
                Once everything is in place, send announcements to <literal>users@ws.apache.org</literal>
                and <literal>announce@apache.org</literal>. Since the two lists have different conventions, audiences
                and moderation policies, to send the announcement separately to the two lists.
            </para>
            <para>
                Sample announcement:
            </para>
            <blockquote>
                <para>
                    Apache Axiom Team is pleased to announce the release of Axiom x.y.z. The release is available
                    for download at:
                </para>
                <para>
                    http://ws.apache.org/axiom/download.cgi
                </para>
                <para>
                    Apache Axiom is a StAX-based, XML Infoset compliant object model which supports on-demand building
                    of the object tree. It supports a novel "pull-through" model which allows one to turn off the tree
                    building and directly access the underlying pull event stream. It also has built in support for
                    XML Optimized Packaging (XOP) and MTOM, the combination of which allows XML to carry binary
                    data efficiently and in a transparent manner. The combination of these is an easy to use API
                    with a very high performant architecture!
                </para>
                <para>
                    Developed as part of Apache Axis2, Apache Axiom is the core of Apache Axis2. However, it is a
                    pure standalone XML Infoset model with novel features and can be used independently of Apache Axis2.
                </para>
                <para>
                    Highlights in this release:
                </para>
                <itemizedlist>
                    <listitem>
                        <para>
                            ...
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            ...
                        </para>
                    </listitem>
                </itemizedlist>
                <para>
                    Resolved JIRA issues:
                </para>
                <itemizedlist>
                    <listitem>
                        <para>
                            [WSCOMMONS-513] Behavior of insertSiblingAfter and insertSiblingBefore is not well defined for orphan nodes
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            [WSCOMMONS-488] The sequence of events produced by OMStAXWrapper with inlineMTOM=false is inconsistent
                        </para>
                    </listitem>
                </itemizedlist>
            </blockquote>
            <para>
                For <literal>users@ws.apache.org</literal>, the subject (<quote>Axiom x.y.z released</quote>) should be
                prefixed with <quote>[ANN][Axiom]</quote>, while for <literal>announce@apache.org</literal>
                <quote>[ANN]</quote> is enough. Note that mail to <literal>announce@apache.org</literal> must be
                sent from an <literal>apache.org</literal> address.
            </para>
        </section>
        <section>
            <title>Post-release actions</title>
            <itemizedlist>
                <listitem>
                    <para>
                        Update the DOAP file (see <filename>etc/axiom.rdf</filename>) and add a new entry
                        for the release.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Update the status of the release version in the AXIOM project in JIRA.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Remove archived releases from <link xlink:href="https://dist.apache.org/repos/dist/release/ws/axiom/"/>.
                    </para>
                </listitem>
            </itemizedlist>
        </section>
        <section>
            <title>References</title>
            <para>
                The following documents are useful when preparing and executing the release:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        <link xlink:href="http://www.apache.org/legal/src-headers.html">ASF Source Header and Copyright Notice Policy</link>
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <link xlink:href="http://apache.org/foundation/marks/pmcs">Apache Project Branding Guidelines</link>
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <link xlink:href="http://projects.apache.org/doap.html">DOAP Files</link>
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <link xlink:href="http://www.apache.org/dev/release-publishing.html">Publishing Releases</link>
                    </para>
                </listitem>
            </itemizedlist>
        </section>
    </chapter>
    
    <appendix>
        <title>Appendix</title>
        <section xml:id="install.ibm.jdk">
            <title>Installing IBM's JDK on Debian Linux</title>
            <procedure>
                <step>
                    <para>
                        Make sure that <literal>fakeroot</literal> and <literal>java-package</literal>
                        are installed:
                    </para>
                    <screen># <userinput>apt-get install fakeroot java-package</userinput></screen>
                </step>
                <step>
                    <para>
                        Download the <filename>.tgz</filename> version of the JDK from
                        <link xlink:href="http://www.ibm.com/developerworks/java/jdk/linux/download.html"/>.
                    </para>
                </step>
                <step>
                    <para>
                        Edit <filename>/usr/share/java-package/ibm-j2sdk.sh</filename> and (if necessary)
                        add an entry for the particular version of the IBM JDK downloaded in the previous
                        step.
                    </para>
                </step>
                <step>
                    <para>
                        Build a Debian package from the tarball:
                    </para>
                    <screen>$ <userinput>fakeroot make-jpkg <replaceable>xxxx</replaceable>.tgz</userinput></screen>
                </step>
                <step>
                    <para>
                        Install the Debian package.
                    </para>
                </step>
            </procedure>
        </section>
    </appendix>
</book>
