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

Quick Guide to Maven for Axis2
==============================

The Axis2 build uses [Maven 3](https://maven.apache.org/). To build the source code, use the
following command:

    mvn clean install

The build may fail because Maven runs out of memory. To avoid this, increase the heap
size (and PermGen size, unless you are using Java 8 or above) using the `MAVEN_OPTS`
environment variable, as shown in the following example:

    MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=256m"

Note that depending on your platform and Java version, you may need to adjust these
values further.

Other useful build commands:

*   Skip test execution: `mvn clean install -DskipTests=true`

*   Simulate a release build: `mvn clean install -Papache-release -Dgpg.skip=true`

*   Build the site: `mvn site` (in the root directory of the source tree)

*   Quick build of the site without Javadocs: `mvn site -N`

For more information, consult the Maven documentation.
