 ------
 Introduction
 ------
 Maria Odea Ching
 Vincent Siveton
 Dennis Lundberg
 ------
 2014-09-06
 ------

~~ 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.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html

${project.name}

 The Javadoc Plugin uses the Javadoc tool to generate javadocs for the specified project.
 For more information about the standard Javadoc tool, please refer to
 {{{http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html}Reference Guide}}.

 The Javadoc Plugin gets the parameter values that will be used from the plugin configuration specified in the pom.
 To hold all javadoc arguments, packages or files, the Javadoc Plugin generates
 {{{http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#argumentfiles}argument files}}
 and calls the Javadoc tool as follow:

+-----+
javadoc.exe(or .sh) @options @packages | @argfile
+-----+

 When no configuration values are set, the plugin sets default values instead and then executes the Javadoc tool.

 You can also use the plugin to package the generated javadocs into a jar file for distribution.

* Goals Overview

   The Javadoc Plugin has 14 goals:

   * {{{./javadoc-mojo.html}javadoc:javadoc}} generates the Javadoc files for the project. It executes the standard
     Javadoc tool and supports the parameters used by the tool.

   * {{{./test-javadoc-mojo.html}javadoc:test-javadoc}} generates the test Javadoc files for the project. It executes
     the standard Javadoc tool and supports the parameters used by the tool.

   * {{{./javadoc-no-fork-mojo.html}javadoc:javadoc-no-fork}} generates the Javadoc files for the project.
     It executes the standard Javadoc tool and supports the parameters used by the tool without forking the 
     <<<generate-sources>>> phase again. Note that this goal does require generation of test sources before site generation, e.g.
     by invoking <<<mvn clean deploy site>>>.

   * {{{./test-javadoc-no-fork-mojo.html}javadoc:test-javadoc-no-fork}} generates the test Javadoc files for the project. 
     It executes the standard Javadoc tool and supports the parameters used by the tool without forking the 
     <<<generate-test-sources>>> phase again. Note that this goal does require generation of test sources before site generation,
     e.g. by invoking <<<mvn clean deploy site>>>.

   * {{{./aggregate-mojo.html}javadoc:aggregate}} generates the Javadoc files for an aggregator project. It executes
     the standard Javadoc tool and supports the parameters used by the tool.

   * {{{./test-aggregate-mojo.html}javadoc:test-aggregate}} generates the test Javadoc files for an aggregator project.
     It executes the standard Javadoc tool and supports the parameters used by the tool.

   * {{{./jar-mojo.html}javadoc:jar}} creates an archive file of the generated Javadocs. It is used during
     the release process to create the Javadoc artifact for the project's release.  This artifact is uploaded
     to the remote repository along with the project's compiled binary and source archive.

   * {{{./test-jar-mojo.html}javadoc:test-jar}} creates an archive file of the generated Test Javadocs.

   * {{{./aggregate-jar-mojo.html}javadoc:aggregate-jar}} creates an archive file of the generated Javadocs for an
     aggregator project.

   * {{{./test-aggregate-jar-mojo.html}javadoc:test-aggregate-jar}} creates an archive file of the generated Test
     Javadocs for an aggregator project.

   * {{{./fix-mojo.html}javadoc:fix}} is an interactive goal which fixes the Javadoc documentation and tags for the
     Java files.

   * {{{./test-fix-mojo.html}javadoc:test-fix}} is an interactive goal which fixes the Javadoc documentation and tags
     for the test Java files.

   * {{{./resource-bundle-mojo.html}javadoc:resource-bundle}} bundles the <<<javadocDirectory>>> along with Javadoc
     configuration options such as taglet, doclet, and link information into a deployable artifact.

   * {{{./test-resource-bundle-mojo.html}javadoc:test-resource-bundle}} bundles the <<<testJavadocDirectory>>> along
     with Javadoc configuration options such as taglet, doclet, and link information into a deployable artifact.

   []

* Usage

  General instructions on how to use the Javadoc Plugin can be found on the {{{./usage.html}usage page}}. Some more
  specific use cases are described in the examples given below.

  In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel
  free to contact the {{{./mail-lists.html}user mailing list}}. The posts to the mailing list are archived and could
  already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching
  the {{{./mail-lists.html}mail archive}}.

  If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our
  {{{./issue-tracking.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your
  concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason,
  entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated.
  Of course, patches are welcome, too. Contributors can check out the project from our
  {{{./source-repository.html}source repository}} and will find supplementary information in the
  {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}.

* Examples

   The following examples show how to use the Javadoc Plugin in more advanced usecases:

   * {{{./examples/aggregate.html}Aggregating Javadocs for Multi-Projects}}

   * {{{./examples/aggregate-dependency-sources.html}Aggregating Dependency Javadocs}}

   * {{{./examples/exclude-package-names.html}Excluding Packages}}

   * {{{./examples/group-configuration.html}Grouping Packages}}

   * {{{./examples/alternate-doclet.html}Using Alternate Doclet}}

   * {{{./examples/alternate-javadoc-tool.html}Using Alternate Javadoc Tool}}

   * {{{./examples/javadoc-resources.html}Using Javadoc Resources}}

   * {{{./examples/output-configuration.html}Using Alternative Output Directory}}

   * {{{./examples/stylesheet-configuration.html}Configuring Stylesheets}}

   * {{{./examples/help-configuration.html}Configuring Helpfile}}

   * {{{./examples/tag-configuration.html}Configuring Custom Javadoc Tags}}

   * {{{./examples/taglet-configuration.html}Configuring Custom Javadoc Taglet}}

   * {{{./examples/links-configuration.html}Configuring Links}}

   * {{{./examples/test-javadocs.html}Generating test Javadocs}}

   * {{{./examples/selective-javadocs-report.html}Selective Javadocs Reports}}

   * {{{./examples/fix-javadocs.html}Fixing Javadoc Comments}}

   * {{{./examples/javadoc-nofork.html}Generate Javadoc without duplicate execution of phase generate-sources}}

   []
