Apache Archiva 使い方メモ

# Apache Archiva とは
リポジトリ管理ソフトウェア。

Maven のリポジトリを簡単に構築することができる。

また、セントラルリポジトリなどのリモートリポジトリをプロキシしたり、ユーザー・権限管理、リポジトリのブラウズ、インデックス化することによる高速な検索など、様々な機能を提供している。

同種のソフトウェアとして [Nexus Repository OSS](http://www.sonatype.com/nexus-repository-oss) や [Artifactory](https://www.jfrog.com/open-source/) というものが存在する。

Nexus などは npm のリポジトリにも対応していたりと、 Archiva より高機能なところがある。

# 環境
## OS
Windows 10

## Java
1.8.0_92

## Apache Archiva
2.2.1

# Hello World
## インストール
[公式サイト](https://archiva.apache.org/download.cgi) からダウンロードする。

zip(tar) と war が配布されている。
zip の方は、 Apache Archiva を単独（スタンドアロン）で動かしたい場合に使用する。
Jetty が内蔵されており、それが利用される。

すでに Tomcat などの Servlet コンテナがインストールされており、そこにデプロイする形で利用したい場合は war を使用する。

今回は zip のほうを選択した。

zip を任意の場所に解凍したら、インストールは完了。

# 起動する
解凍してできたフォルダの下の `bin` フォルダの下でコマンドラインを開き、以下のコマンドを実行する。

```bash
> archiva console
```

サーバーが起動するので、ブラウザを開いて `http://localhost:8080/` にアクセスする。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/79fca027-03ba-2c6c-a847-f69563be8537.jpeg)

停止は `Ctrl` + `C`。

## 管理者ユーザーを作成する
右上の `Create Admin User` ボタンをクリックする。
すると、管理者ユーザーの作成画面が開くので、必要な項目を入力して管理者ユーザーを作成する。

## 動作確認
デフォルトで、 `internal` と `snapshots` というリポジトリが作成されている。
`internal` はリリース版（安定板）のアーティファクトを置くためのリポジトリで、 `snapshots` はスナップショット（開発版）のアーティファクトを置くためのリポジトリ設定になっている。

メニューの `Repositories` を選択するとリポジトリの一覧が表示される。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/ec96bc6a-aa85-9ad8-b0dc-14b2e771eaea.jpeg)

`internal` はセントラルリポジトリのプロキシとして設定済みになっている。

試しに `http://localhost:8080/repository/internal/junit/junit/3.8.1/junit-3.8.1.jar` にブラウザからアクセスすると、 jar ファイルがダウンロードできる。
裏では、 Apache Archiva が Maven のセントラルリポジトリにアクセスして jar をダウンロードし、ローカルにキャッシュしてからブラウザに返すという動作をしている。

一度ダウンロードした jar は `【Apache Archiva のインストールフォルダ】/repositories/internal` の下に保存される。
二回目以降同じ jar にアクセスすると、このローカルに保存された jar が使用されるため、セントラルリポジトリへのアクセスは発生しなくなる。

また、一度ダウンロードした情報は、 Apach Archiva 上で検索やブラウズなどが可能になる。
メニューの `Search` や `Browse` から検索や閲覧ができる。

# サービスとして登録してバックグラウンドで動かす
Windows にサービスとしてインストールして、バックグラウンドで起動できるようにする。

管理者権限でコマンドプロンプトを開き、 `bin` の下に移動して以下のコマンドを実行する。

```bash
> archiva install
```

これで、 Apache Archiva がサービスとして登録されるようになる。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/4e7183ac-3c78-4fb3-1e01-7c3b5bed0de4.jpeg)

あとは、サービスの設定で自動起動にしておけば、マシン起動時に勝手に立ち上がるようになる。

コマンドで起動・停止を制御したい場合は、管理者権限で以下のコマンドを実行する。

```bash
# 起動
> archiva start

# 停止
> archiva stop

# 状態の確認
> archiva status
```

サービスからアンインストールしたい場合は、管理者権限で以下のコマンドを実行する。

```bash
> archiva remove
```

# ポート番号を変更する
`conf/jetty.xml` を開いて、以下のように修正する。

```diff:jetty.xml
    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="host"><SystemProperty name="jetty.host"/></Set>
-           <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
+           <Set name="port"><SystemProperty name="jetty.port" default="9090"/></Set>
            <Set name="maxIdleTime">30000</Set>
            <Set name="Acceptors">2</Set>
            <Set name="statsOn">false</Set>
            <Set name="confidentialPort">8443</Set>
            <Set name="lowResourcesConnections">5000</Set>
            <Set name="lowResourcesMaxIdleTime">5000</Set>
          </New>
      </Arg>
    </Call>
```

これで 9090 ポートで起動するようになる。


# Gradle から Apache Archiva を利用する
```groovy:build.gradle
apply plugin: 'java'

repositories {
    maven {
        url 'http://localhost:8080/repository/internal'
    }
}

dependencies {
    compile 'commons-dbcp:commons-dbcp:1.4'
}
```

- `repositories` で今まで `mavenCentral()` と設定していたところを、 Apache Archiva を見るように変更する。
- 各リポジトリは `/repository/<リポジトリ名>` で参照できる。
    - たぶん、 Tomcat とかにデプロイしている場合は `/repository` の前にコンテキストパスが必要。

# リポジトリを新規作成する
- メニューの [Repositories] を選択する。
- [Add] をクリック。
- 以下を入力する。

|項目名|説明|例|
|---|---|---|
|`Id`|リポジトリを識別する一意なID。|`test_repository`|
|`Name`|リポジトリの名前（英数字のみ）。|`Test Repository`|
|`Directory`|リポジトリの設定やキャッシュを保存するディレクトリのパス。|`./repositories/test_repository`|
|`Index Directory`|インデックスファイルの保存先。未指定の場合は `Directory` の直下に `.indexer` という名前で作られる。|`./repositories/test_repository/.indexer`|
|`Type`|リポジトリの種類（Maven 2.x Repository しか選べない）。|`Maven 2.x Repository`|
|`Cron Expression`|リポジトリのスキャンを実行するタイミングを `cron` 風に設定する。|`0 0 * * * ?`|
|`Days Older`|スナップショット版のアーティファクトを何日間保持しておくかの設定。|`30`|
|`Retention Count`|スナップショット版のアーティファクトを何個前まで保持しておくかの設定。|`2`|
|`Description`|リポジトリの説明（日本語可）。|テスト用リポジトリ|
|`Releases`|リリース版のアーティファクトを含めるかどうか。|`true`|
|`Snapshots`|スナップショット版のアーティファクトを含めるかどうか。|`false`|
|`Block Redeployments`|既にリポジトリに存在するアーティファクトの再デプロイをブロックするかどうか。|`true`|
|`Scanned`|リポジトリのスキャンを有効にするかどうか。|`true`|
|`Delete Released Snapshots`|リポジトリのパージ中に、既にリリース版が上げられているアーティファクトがあった場合、そのスナップショット版を削除するかどうか。|`false`|
|`Staging Repository`|ステージング用のリポジトリを自動で生成するかどうか。|`false`|
|`Skip Packed Index creation`|IDE 用に圧縮されたインデックスを作成しない。|`false`|

- 必要な設定を入力したら、 [Save] で保存。

## 権限を設定する
新規作成された直後のリポジトリは、一般ユーザーからは参照もできない状態になっている。
誰でも参照できるように、 `guest` ユーザーに権限を設定する。

- メニューの [Manage] を選択する。
- `guest` の [Edit] を選択する。
- [Edit Roles] を選択する。
- [Repository Observer] に `test_repository` が存在するので、チェックをオンにする。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/b649be35-25e0-9250-419c-75d7467b279e.jpeg)

- [Update] をクリックして完了。

# Maven のセントラルリポジトリのプロキシとして動作させる
作成したリポジトリは、そのままだとただの素のリポジトリとしてしか動作しない。
Maven のセントラルリポジトリのプロキシとして動作させるには、メニューの [Proxy Connectors] を選択する。

- [Add] を選択。
- 以下を設定。

|項目名|説明|例|
|---|---|---|
|`Network Proxy`|ネットワークのプロキシサーバーを介する場合は設定する（詳細後述）。|`direct connection`|
|`Managed Repository`|Apache Archiva が管理しているリポジトリを選択する。|`test_repository`|
|`Remote Repository`|プロキシするリモートのリポジトリを選択する。|`central`|

- `Pollicies` については、正直よくわからなかった。
    - `Checksum` は checksum のチェックに失敗したときにどうするかの設定なんだろうけど、 `fix` ってなに？
    - `Snapshots` と `Releases` は、リポジトリに問い合わせる頻度だろうか？
    - それ以外は、主にエラーがあったときにどうするか、といった設定ぽいけど、厳密な意味はよく分からなかった。
- とりあえずデフォルトのままにして、 [Save] で保存する。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/f4bdbfa5-27b5-7660-be95-eb83035c7e3f.jpeg)

ブラウザで `http://localhost:8080/repository/test_repository/junit/junit/3.8.1/junit-3.8.1.jar` にアクセスすれば、 junit の jar がダウンロードされる（リポジトリ名の部分は、必要であれば実際に登録したリポジトリ名に要変更）。

## セントラルリポジトリ以外をプロキシする
デフォルトではセントラルリポジトリがリモートリポジトリとして登録されている。
これ以外にも、任意の Maven リポジトリをリモートリポジトリとして登録することができる。

試しに [Seasar2 の Maven リポジトリ](http://maven.seasar.org/) を登録してみる。

- メニューの [Repositories] を選択。
- [Remote Repositories Management] タブを選択する。
- [Add] を選択。
- 以下を入力（設定したものだけ）。

|項目名|設定値|
|---|---|
|`Id`|`seasar2`|
|`Name`|`Seasar2 Repository`|
|`Url`|`http://maven.seasar.org/maven2/`|
|`Type`|`Maven 2.x Repository`|

- [Save] で保存。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/f634827f-7e04-f52f-9537-96965f3ffa32.jpeg)

リモートリポジトリが追加できたので、先ほど作成した `test_repository` とこのリモートリポジトリを紐づける。

- メニューの [Proxy Connectors] を選択。
- `Add` を選択して、 `test_repository` と `seasar2` を紐づけるように設定する。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/238fc654-a3a7-64cb-b474-fa77a2978bd7.jpeg)

ブラウザで `http://localhost:8080/repository/test_repository/net/arnx/jsonic/jsonic/1.2.0/jsonic-1.2.0.jar` にアクセスしてみて、 jar がダウンロードできることを確認する。

設定画面を見ると一番右のところに `Order Edition` というのがある。
これを選択すると、アーティファクトを検索するときの優先順序を指定できる。
（Chrome だと JavaScript エラーになった。Edge だと動いた）


# ライブラリをアップロードする
## 画面から jar をアップロードする
- アップロードしたい jar を用意する。
- メニューの [Upload Artifact] を選択する。
- 以下を入力。

|項目名|説明|例|
|---|---|---|
|`Repository Id`|アップロード先のリポジトリ。|`Test Repository`|
|`Group ID`|アーティファクトのグループID。|`mine`|
|`Artifact ID`|アーティファクトのID。|`mylib`|
|`Version`|アーティファクトのバージョン。|`1.0.0`|
|`Packaging`|アーティファクトのパッケージ種別（`jar`, `war`, `ear` など）。|`jar`|
|`Generate Maven POM`|pom ファイルを自動で生成されるか。|`true`|

- アップロードしたい jar を画面にドラッグ＆ドロップする。
- [Start Upload] をクリック。
- [Save Files] をクリック。

アップロードが成功すると、成功のメッセージが表示される。

### アップロードされたファイルを確認する。
アップロードされてすぐは変更が反映されないようで、自分の環境では以下の操作をすることで [Search] から検索できるようになった。

- メニューの [Repositories] を選択する。
- `test_repositories` の [Actions] を開き、 [Directories Scanning] と [Index Scanning] を実行。

あとは、しばらく待っていたら、 [Browse] からも見れるようになった。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/b6f6bbe7-7182-c1f9-a2ca-723b091897d8.jpeg)

## Gradle からアップする
### ユーザーを作成する
`guest` ユーザーにアップロード権限をつけてもいいけど、誰でもアップできる状態にするのはアレな気がするので、専用のユーザーを作ってそれでアップロードしてみる。

- メニューの [Manage] を選択。
- [Add] を選択。
- 各項目を入力して [Save] を選択。
    - 今回は `deployer` という名前のユーザーを作ってみた。
- 作成された `deployer` ユーザーの [Edit] を選択する。
- [Edit Roles] を選択する。
- [Repository Manager] の `test_repository` にチェックを入れる。
- [Update] で保存。

### build.gradle を作成する
```groovy:build.gradle
apply plugin: 'java'
apply plugin: 'maven' // maven プラグインを有効にする

repositories {
    mavenCentral()
}

// groupId
group = 'mine'
// artifactId
jar.baseName = 'mylib'
// version
version = '1.0.0'

uploadArchives {
    repositories {
        mavenDeployer {
            // Archiva のリポジトリを指す URL を設定
            repository(url: 'http://localhost:8080/repository/test_repository') {
                // 先ほど作成した、アップロード用のユーザー名とパスワードを指定
                authentication(userName: 'deployer', password: 'deployer9')
            }
        }
    }
}

// 以下、ソースコードと Javadoc も一緒にアップするための記述
task sourcesJar(type: Jar, dependsOn:classes) {
     classifier = 'sources'
     from sourceSets.main.allSource
}

task javadocJar(type: Jar, dependsOn:javadoc) {
     classifier = 'javadoc'
     from javadoc.destinationDir
}

artifacts {
     archives sourcesJar
     archives javadocJar
}
```

### アップロードを実行する
```bash
> gradle uploadArchives
```

上記コマンドでアップロードが実行される。

# ネットワークプロキシの設定
社内から外部に接続するときにネットワークプロキシを介さなければならない場合に設定する。

- メニューの [Network Proxies] を選択。
- [Add] を選択。
- 必要な項目を入力して [Save] を選択。

ここで登録したプロキシの設定は、 [Proxy Connectors] の [Network Proxy] で選択できるようになる。

# パスワードの有効期限設定を変更する
コメントで @sh-ogawa さんに教えていただきました。ありがとうございます。

## <font color="red">注意事項</font>

ここで説明している操作を、ブラウザにログインユーザのパスワードを記録した状態で実行すると、エラーが発生して<font color="red"> Archiva が起動しなくなります</font>。

理由は、 [LDAP] タブを開くとわかります。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/901ea30d-4a5e-ab70-3ab1-da13ce7b12e3.jpeg)

ブラウザでパスワードを記録して自動でログイン情報を埋め込む設定にしていると、 LDAP タブの [bindDn] と [password] に記録されているログイン情報が勝手に入力されます。

これに気付かずに [Save] を実行すると、 Archiva は起動時に LDAP への接続を試みるようになり、結果エラーが発生して Archiva が起動しなくなります。

Archiva ではパスワードを記録しないようにするか、毎回 LDAP のタブを開いて [bindDn] と [password] を空にしてから [Save] を実行するなどの対処が必要です。

注意事項ここまで...

----

デフォルトだとパスワードには有効期限があり、 90 日で失効してしまう。
実際に日数を待って確認はできていないが、おそらく以下の操作で設定を変更できる。

- メニューの [Users Runtime Configuration] を選択する。
- [Properties] タブを開く。
- いくつかページを進めると、 `security.policy.password.expiration.***` という設定が出てくる。
- `security.policy.password.expiration.enable` を `false` にすれば、たぶん有効期限の管理が無効になる（失効しなくなる）。
- `security.policy.password.expiration.days` を変更すれば、たぶん有効期限の長さ（日数）を変更できる。

![apache_archiva.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/7b92cdd2-c6f3-e560-2fcf-03b82a9bfa70.jpeg)


# 参考
- [Archiva – The Build Artifact Repository Manager](https://archiva.apache.org/index.cgi)
- [Apache Archiva を試す](http://www.slideshare.net/bouzuya/apache-archiva)
- [Apache Archivaを使ってみる - amutan日記](http://d.hatena.ne.jp/amutan/20100207/1265542945)
- [GradleでMavenリポジトリにデプロイする時のメモ - wadahiroの日記](http://wadahiro.hatenablog.com/entry/2012/07/24/234727)