//
// Licensed 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.
//

=== Installation

Apache Karaf is a lightweight container, very easy to install and administrate, on both Unix and Windows platforms.

==== Requirements

*Hardware:*

* 50 MB of free disk space for the Apache Karaf binary distribution.

*Operating Systems:*

* Windows: Windows 8, Windows 7, Windows 2003, Windows Vista, Windows XP SP2, Windows 2000.
* Unix: RedHat Enterprise Linux, Debian, SuSE/OpenSuSE, CentOS, Fedora, Ubuntu, MacOS, AIX, HP-UX, Solaris, any Unix platform that supports Java.

*Environment:*

* Java SE 1.7.x or greater (http://www.oracle.com/technetwork/java/javase/).
* The JAVA_HOME environment variable must be set to the directory where the Java runtime is installed,

==== Using Apache Karaf binary distributions

Apache Karaf is available in two distributions, both as a tar.gz and zip archives.

The "default" distribution is a "ready to use" distribution, with pre-installed features.

The "minimal" distribution is like the minimal distributions that you can find for most of Unix distributions.
Only the core layer is packaged, most of the features and bundles are downloaded from Internet at bootstrap.
It means that Apache Karaf minimal distribution requires an Internet connection to start correctly.
The features provided by the "minimal" distribution are exactly the same as in the "default" distribution, the difference
is that the minimal distribution will download the features from Internet.

===== Installation on Windows platform

[NOTE]
====
The JAVA_HOME environment variable has to be correctly defined. To accomplish that, press Windows key and Break key together, switch to "Advanced" tab and click on "Environment Variables".
====

. From a browser, navigate to http://karaf.apache.org/index/community/download.html.
. Download Apache Karaf binary distribution in the zip format: `apache-karaf-4.0.0.zip`.
. Extract the files from the zip file into a directory of your choice (it's the `KARAF_HOME`.

[NOTE]
====
Remember the restrictions concerning illegal characters in Java paths, e.g. \!, % etc.
====

[NOTE]
====
In case you have to install Karaf into a very deep path or a path containing illegal characters for Java paths, e.g. \!, % etc., you may add a bat file to _start \-> startup_ that executes

----
subst S: "C:\your very % problematic path!\KARAF"
----

so your Karaf root directory is S: --- which works for sure and is short to type.
====

===== Installation on Unix platforms

[NOTE]
====
The JAVA_HOME environment variable has to be correctly defined. Check the current value using

----
echo $JAVA_HOME
----

If it's not correct, fix it using:

----
export JAVA_HOME=....
----
====

. From a browser, navigate to http://karaf.apache.org/index/community/download.html.
. Download Apache Karaf binary distribution in the tar.gz format: `apache-karaf-4.0.0.tar.gz`.
. Extract the files from the tar.gz file into a directory of your choice (it's the `KARAF_HOME`). For example:

----
gunzip apache-karaf-4.0.0.tar.gz
tar xvf apache-karaf-4.0.0.tar
----

[NOTE]
====
Remember the restrictions concerning illegal characters in Java paths, e.g. \!, % etc.
====

==== Post-Installation steps

Thought it is not always required, it is strongly advised to set up the `JAVA_HOME` environment property to point to the JDK you want Apache Karaf to use before starting it.
This property is used to locate the `java` executable and should be configured to point to the home directory of the Java SE 7 installation.

By default, all Apache Karaf files are "gather" in one directory: the `KARAF_HOME`.

You can define your own directory layout, by using some Karaf environment variables:

* `KARAF_DATA` is the location of the data folder, where Karaf stores temporary files.
* `KARAF_ETC` is the location of the etc folder, where Karaf stores configuration files.
* `KARAF_BASE` is the Karaf base folder. By default `KARAF_BASE` is the same as `KARAF_HOME`.

==== Building from Sources

If you intend to build Apache Karaf from the sources, the requirements are a bit different:

*Hardware:*

* 500 MB of free disk space for the Apache Karaf source distributions or SVN checkout, the Maven build and the dependencies Maven downloads.

*Environment:*

* Java SE Development Kit 1.7.x or greater (http://www.oracle.com/technetwork/java/javase/).
* Apache Maven 3.0.4 or greater (http://maven.apache.org/download.html).

===== Building on Windows platform

You can get the Apache Karaf sources from:

* the sources distribution `apache-karaf-4.0.0-src.zip` available at http://karaf.apache.org/index/community/download.html. Extract the files in the directory of your choice.
* by checkout of the git repository:

----
git clone https://git-wip-us.apache.org/repos/asf/karaf.git karaf
----

Use Apache Maven to build Apache Karaf:

----
mvn clean install
----

[NOTE]
====
You can speed up the build by bypassing the unit tests:

----
mvn clean install -DskipTests
----
====

Now, you can find the built binary distribution in `assemblies\apache-karaf\target\apache-karaf-4.0.0.zip`.

===== Building on Unix platforms

You can get the Apache Karaf sources from:

* the sources distribution `apache-karaf-4.0.0-src.tar.gz` available at http://karaf.apache.org/index/community/download.html. Extract the files in the directory of your choice.
* by checkout of the git repository:

----
git clone https://git-wip-us.apache.org/repos/asf/karaf.git karaf
----

Use Apache Maven to build Apache Karaf:

----
mvn clean install
----

[NOTE]
====
You can speed up the build by bypassing the unit tests:

----
mvn clean install -DskipTests
----
====

Now, you can find the built binary distribution in `assemblies/apache-karaf/target/apache-karaf-4.0.0.tar.gz`.
