JOSMプラグイン開発環境を整備する

# JOSMプラグイン開発環境を整備する

OSMのエディタとして古くから利用されている[JOSM](https://wiki.openstreetmap.org/wiki/JA:JOSM)にはJOSMの機能を強化する[JOSMプラグイン](https://josm.openstreetmap.de/wiki/Ja%3APlugins)というものがある

JOSMプラグインの開発方法は「[https://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins](https://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins)」に記載されています。<br/>以上

なのだが、JOSMの「[JOSMプラグイン開発ガイド](https://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins)」では「[テンプレート](https://trac.openstreetmap.org/browser/applications/editors/josm/plugins/00_plugin_dir_template)を示すからこれで開発できるだろ」的な書き方になっているので、私には**敷居が高すぎて**手に負えなかった

2017年12月に *救世主現る*。 maripoさまの「[JOSMのプラグイン作ろうぜ](https://blog.maripo.org/2017/12/josm-plugin-dev/)」が発表された。これでやっと「*ひょっとしたら俺でもできるんじゃね？*」って気分になってきた。

だがしかし、気分だけではどうにもならず、肝心のプログラミングを開始する前の開発環境の準備段階で「DevelopingPlugins」にてこづらされた。

* 英語で書かれてる
* のっけから `svn` でつまづく
* `ant`が懐かしすぎる
* 結局 *JOSMプラグイン*のプロジェクトはどこにつくるの？
* 日本語化したいけどどうすればいいの？

と、*JOSMプラグイン*開発に着手するまでの手順が難しすぎる。(週末プログラマーの私は２ヶ月かかった)

ということで これから*JOSMプラグイン*開発を始めようとする人や、開発再開する人に向けて、同じような苦労をせずにグログラミングを開始できるように JOSMプラグインの開発環境を整備する手順を示す


# 事前準備

作業に取り掛かる前に下ごしらえ

* 開発マシンのOSは 「Linux mint 19 (Ubuntu 18.04 bionic)」を使っている
  > JOSMに限らず、OSMの世界はLinuxが標準だ、同じUNIX系の *MacOS* でも問題はないが、*Windows*での開発はおすすめしない

* プロジェクトはホームディレクトリの下に「`workspace`」が作成されているものとして説明する。「`workspace`」が作成されていない場合には作っておいてくれ。
  * `$ mkdir ~/workspace`

* `Java`のインストール (`JOSM`は`java`で書かれている)
  * インストール `OpenJDK 1.8` : JOSMは `java 1.8`以降で動作するように作らないといけないから、
  * インストール `OpenJDK 11` JOSMプラグインの部分は `java 11` でないとコンパイルできないものが混じっているので...
  > `OpenJDK 1.8`と`OpenJDK 11`の両方ともインストールしてくれ

* IDEには *Eclipse* を使うぞ
  * `eclipse IDE`
    * 「Eclipse」は各自でインストールしておいてくれ

  > わたしはJOSMプラグインをいじるために、10年以上愛用してきた *netbeans* から *eclipse* に転んだ...

* その他、下記もインストールしておいてくれ
  * 「`svn`」
    * `# apt install svn` ← 確かこんな感じ、svnクライアントだけでOK
  * 「`git`」
    * `# apt install git`


# 1. ベースJOSMを準備する

まずはじめに、JOSMプラグインが動作する「ベースJOSM」をビルドする。

![dev1_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/1a0e112c-1b99-f3e2-7217-5dc95396c920.png)


まずは、JOSMプラグインが動作する基礎部分をつくる。

JOSMのバイナリじゃだめなんだ。ソースからビルドするよ

## (1) ベースJOSMのソース取得

JOSMのソースを取得する。JOSMのソースは`svn(Subversion)`で配信されている

`svn`の知識は必要ない、下記のコマンドをそのまま実行するだけ

```
$ cd ~/workspace

$ svn co https://josm.openstreetmap.de/osmsvn/applications/editors/josm
```

* フォルダ`~/workspace/josm` が作成される。


## (2) JOSM更新

すでにJOSMのコードを取得済みの場合は最新のコードにアップデートする

```
$ cd ~/workspace/josm

$ svn update
```

## (3) JOSMのビルド

ここで取得した`JOSM`をIDEを使わずにコマンドラインから手動でビルドする

### (3-1) Javaのバージョンを `JDK1.8` に切り替える

JOSMは`Java 1.8`以降に対応させなければならないので java1.8でコンパイルする

* `sudo update-alternatives --config java`
* `sudo update-alternatives --config javac`

  ```
  Selection    Path                                                     Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java               1111      manual mode
* 1            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java            1081      manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
  ```

### (3-2) Josm/coreをビルドする

```
$ cd ~/workspace/josm/core

$ ant
　：
BUILD SUCCESSFUL
Total time: 14 seconds
```

`BUILD SUCCESSFUL`が表示されれば成功だ


## (4) Eclipseによる JOSMビルド

ベースとなる`JOSM`をビルドしたら Eclipseでもビルドできるようにする

JOSMの公式Wikiには「Eclipse」での開発方法が記載されているので、ここでも素直に「Eclipse」を使う

Eclipseを起動する前に Javaのバージョンを'Java 11'に戻す

* `sudo update-alternatives --config java`
* `sudo update-alternatives --config javac`

```
  Selection    Path                                                  Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/javac           1111      manual mode
  1            /usr/lib/jvm/java-8-openjdk-amd64/bin/javac            1081      manual mode

Press <enter> to keep the current choice[*], or type selection number: 0
```

* Eclipse IDE 2020-12
  * `Eclipse`を起動する

### (4-1) [JOSM]プロジェクトの作成

- 「`~/workspace/jsom/core/build.xml`」 を antプロジェクトとしてインポートする<br/>![step1_006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/eecec94a-50a0-bddf-12a2-402dab414104.png)

  - Eclipse メニュー → [`File(F)`] → [`新規(N)`] → [`その他(O)...`]
  
  - 'ウィザードを選択'<br/>![step1_007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/67eda23f-30fb-6a05-6a62-08e5128043d8.png)
    - [`Java Project from Existing Ant Buildfile` / `既存 Ant ビルドファイルからの Java プロジェクト`]
    - [`次へ(N) >`]
    
  - 'Ant ビルドファイルからの Java プロジェクト作成'<br/>![step1_008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/59c73af7-f177-9f89-c17f-724724b543d1.png)
    - '`Antビルドファイル(A)`': [`~/workspace/josm/core/build.xml`]
    - '`プロジェクトの定義に使用するJavac宣言を選択(S)`': [`< >ターゲット"compile"に"javac"タスクが見つかりました`]
    - [`完了(F)`]

  - 'プロジェクト作成でエラーが発生しました'<br/>![step1_009err.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/b704cc0f-7295-31c7-4ffa-d31329f6163e.png)
    - エラー[`Reference runtime.path not found.`]が発生するが、後ほど対処するので無視して先に進める
    - [`OK`]

プロジェクト[`JOSM`]が作成される
![step1_010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/fbd73f1a-a717-90da-2577-14fc8bfadfcb.png)


### (4-2) [JOSM]プロジェクトの設定変更

作成されたプロジェクト[`josm`]の設定を手作業で修正していく

- プロジェクト[`josm`]を`右クリック` → [`properties` / `プロパティ(R)`]
  - '`Resource`':
    - '`ロケーション`':	[`~/workspace/josm`]
  - '`ビルダー`': [`新規 antビルダー`]
    - [`構成の編集`]
      - タブ[`メイン`]<br/>![step1_012main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/f392a315-1f38-068d-5dea-a4fac0ae2676.png)
        - '`Ant buildfile` / `ビルドファイル(L)`':　[`${workspace_loc:/josm/core/build.xml}`]
        - [`適用(Y)`]
      - タブ[`JRE`]<br/>![step1_012jre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/f9532d39-64bc-ca22-ac0b-9b4233353e41.png)
        - '`Runtime JRE` / `ランタイムJRE`':
          - 別のJRE(P): [`java-8-openjdk-amd64`]
        - [`適用(Y)`]
  - '`Java Build Path` / `Javaのビルドパス`'
    - '`Libraries` / `ライブラリー(L)`'<br/>![step1_013lib.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/6afcde8d-32ec-b055-d3f2-e0c9283aa671.png)
      - '`JARの追加(J)...`': 　[`josm/core/dist/josm-custom.jar`]
      - '`ライブラリの追加(l)...`':  [`JRE System Library [java-11-openjdk-amd64]`]
      - '`ライブラリの追加(l)...`':  [`JUnit5`]
      - [`適用(A)`]
  - Java コンパイラー<br/>![step1_013cmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/f536dc1b-f1a6-1d48-dfbc-41059f2ee616.png)
    - '`プロジェクト固有の設定を可能にする`': [`ON`]
    - '`コンパイラー準拠レベル`':  [`1.8`]
    - '`デフォルトの準拠設定の使用`':　[`OFF`]
      - '`生成された .class ファイルの互換性`':  [`1.8`]
      - '`ソースの互換性`':　[`1.8`]
    - [`適用(A)`]

### (4-3) [JOSM]プロジェクトのビルド

* プロジェクト「`josm`」の「`build.xml`」を`右クリック` → [`実行(R)`]

![JOSM_wiki_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/7297059c-b84a-165a-b2d7-4fc099ee72c8.png)



## (5) Eclipseから「JOSM」を起動する

「`josm`」のビルドに成功したら、Eclipseから「`josm`」を起動してみる

- プロジェクト「`JOSM`」を`右クリック` → 「`実行(R)`」 → 「`Javaアプリケーション`」<br/>![dev1_004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/4fd7c2f5-3912-0ff2-ceba-f98e3c33eaf4.png)

- 「`MainApplication - org.openstreetmap.josm.gui`」を選択<br/>![dev1_005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/b45b3dfe-a05f-99ff-8654-d7364e97d117.png)

- 初回は、JOSMが起動するまでケッコウ時間がかかります。（１分ぐらい）

![dev1_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/24c8c2d0-0767-61cd-8d58-5fbb38846ee0.png)



# 2. JOSMプラグインの開発環境を整備する

ここからは「JOSMプラグイン」を「デバッグモード」で実行できるように環境整備していく

![dev2_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/e0704d92-cdc0-fae3-25bb-eba4676ae02f.png)



## (1) 既存JOSMプラグインの取得[easypresets]プロジェクトの作成

いきなりJOSMのプラグインの開発を開始するのはハードルが高いので、まづは既存のプリセットを動かしてみる

ここでは、maripoさまの「[EasyPresets](https://github.com/maripo/JOSM_easypresets)」をサンプルに使わせてもらう


### (1-1) プラグインのソースコードを取得する

![dev2_git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/f6569f4a-4a14-225a-5273-80b96e997a4c.png)


githubにある「[EasyPresets](https://github.com/maripo/JOSM_easypresets)」を取得する

下記コマンドを打つべし

```
$ cd ~/workspace/josm/plugins

$ git clone https://github.com/maripo/JOSM_easypresets.git easypresets
```

- 「プロジェクト`josm`」の「フォルダ`plugins`」に「フォルダ`easypresets`」が作成される

	```
	$ ll ~/workspace/josm/plugins/easypresets
		合計 124
		drwxr-xr-x   8 hayashi hayashi  4096  2月 21 11:50 .git/
		-rwxr-xr-x   1 hayashi hayashi   114  2月 21 11:50 .gitignore*
		-rwxr-xr-x   1 hayashi hayashi 18092  2月 21 11:50 GPL-v2.0.txt*
		-rwxr-xr-x   1 hayashi hayashi 35147  2月 21 11:50 GPL-v3.0.txt*
		-rwxr-xr-x   1 hayashi hayashi   289  2月 21 11:50 README*
		-rwxr-xr-x   1 hayashi hayashi  4391  2月 21 11:50 README-ja.md*
		-rwxr-xr-x   1 hayashi hayashi  2717  2月 21 11:50 README.md*
		-rwxr-xr-x   1 hayashi hayashi  1463  2月 21 11:50 build.xml*
		drwxr-xr-x   2 hayashi hayashi  4096  2月 21 11:50 data/
		drwxr-xr-x   3 hayashi hayashi  4096  2月 21 11:50 doc/
		drwxr-xr-x   2 hayashi hayashi  4096  2月 21 11:50 i18n/
		-rwxr-xr-x   1 hayashi hayashi   109  2月 21 11:50 i18n_deploy.sh*
		-rwxr-xr-x   1 hayashi hayashi   351  2月 21 11:50 i18n_start.sh*
		drwxr-xr-x   2 hayashi hayashi  4096  2月 21 11:50 images/
		drwxr-xr-x   3 hayashi hayashi  4096  2月 21 11:50 src/
		drwxr-xr-x   4 hayashi hayashi  4096  2月 21 11:50 test/
	```

### (1-2) プロジェクト[easypresets]のインポート

'github'から取得した「フォルダ`easypresets`」を'Eclipse IDE'のプロジェクトとして登録する

- 'Eclipse' → 「`ファイル...`」 → [`ファイルシステムからプロジェクトを開く...`]<br/>![step2_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/06027cb0-1084-e891-1e36-987547bcbf01.png)
    - インポートソース: [`/home/(user)/workspace/josm/plugins/easypresets`]
    - [`完了(F)`]

「プロジェクト`josm`」の中に「プロジェクト`easypresets`」が入れ子になって作成される<br/>![step2_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/b5aa9983-9be1-edaa-a18c-4e9b3008b70c.png)

- 'Eclipse' → 「プロジェクト`josm/plugins/easypresets`」を`右クリック` → [`プロパティ(R)...`]
  - '`Resource` / `リソース`'<br/>![step2_004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/bf8738bd-ca0f-a92b-9325-7443021186e7.png)
    - 'パス(P)': [`/easypresets`]
    - 'ロケーション(L)': [`/home/(user)/workspace/josm/plugins/easypresets`]
    - [`適用(A)`]

  - '`ビルダー`': [`新規 antビルダー`]<br/>![step2_005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/8c173c96-3dd3-089c-3dff-26788ff6dd02.png)
    - [`構成の編集`]
      - タブ[`メイン`]<br/>![step2_005main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/ee14e048-349c-2509-297c-a4746e8264fa.png)
        - '名前(N)':　[`Ant ビルダー`]
        - '`Ant buildfile` / `ビルドファイル(L)`':　[`${workspace_loc:/easypresets/build.xml}`]
      - タブ[`JRE`]<br/>![step2_005jre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/61a07046-3ab1-a187-23c7-f0ee293eb8e8.png)
        - '`Runtime JRE` / `ランタイムJRE`':
          - 別のJRE(P): [`java-11-openjdk-amd64`]

  - '`Java Build Path` / `Javaのビルドパス`'
    - '`Libraries` / `ライブラリー(L)`'<br/>![step2_006lib.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/16b9984e-ba1f-5422-d0b0-1b57e540e3c5.png)
      - '`JARの追加(J)...`': 　[`josm/core/dist/josm-custom.jar`]
      - '`JARの追加(J)...`': 　[`josm/dist/utilsplugin2.jar`]
      - '`ライブラリの追加(l)...`':  [`JRE System Library [java-11-openjdk-amd64]`]
      - '`ライブラリの追加(l)...`':  [`JUnit5`]

  - Java コンパイラー<br/>![step2_006cmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/412a10bc-cbc6-728a-f609-b7fd512fbc13.png)
    - '`プロジェクト固有の設定を可能にする`': [`ON`]
    - '`コンパイラー準拠レベル`':  [`1.8`]
    - '`デフォルトの準拠設定の使用`':　[`OFF`]
      - '`生成された .class ファイルの互換性`':  [`1.8`]
      - '`ソースの互換性`':　[`1.8`]


## (2) EasyPreset 言語変換ファイルを更新する

'(1)'でソースコードを取得した際にすでにコンパイル済みの「言語変換ファイル(`*.lang`)」も含まれているのでわざわざ更新する必要はないのだが、「日本語化」の手順を示すためにここで「`*.lang`」の更新手順を示す

![dev2_i18n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/c21fc902-a256-f68c-b89c-99dc653615dd.png)


`easypresets`には多言語対応用スクリプトが用意されている

`i18n_start.sh`を実行すると`src/*.java`からテキスト部分を抜き出して`i18n/*.po`が作成される

- `src/*.java` からテキスト部分を抜き出して `i18n/*.po` を作ってくれる

  ```
  cd ~/workspace/josm/plugins/easypresets/
  ./i18n_start.sh 
  ```

`i18n/*.po`を編集してくれ

- `~/workspace/josm/plugins/easypresets/i18n/*.po`を作ってくれるのでそれを編集する

`i18n_deploy.sh`を実行すると、`data/*lang`が作成される

- `i18n/*.po` から `data/*.lang` を作成

  ```
  cd ~/workspace/josm/plugins/easypresets/
  ./i18n_deploy.sh
  ```

「参考」
  - [i18n_start.sh](https://github.com/maripo/JOSM_easypresets/blob/pr46/i18n_start.sh)
  - [i18n_deploy.sh](https://github.com/maripo/JOSM_easypresets/blob/pr46/i18n_deploy.sh)


## (3) JOSMプラグインをビルド

![dev2_ant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/209c4d79-6fdf-dba5-6528-54bcf41529e4.png)

プラグインをビルドして、`easypresets.jar`を生成します。

### (3-1) JOSMプラグイン[easypresets]のビルド（コマンド編）

＊ Javaのバージョンを `OpenJDK 11` に切り替える

`sudo update-alternatives --config java`

`sudo update-alternatives --config javac`

```
* 2            /usr/lib/jvm/java-11-openjdk-amd64/bin/javac           1111      手動モード
```

```
cd ~/workspace/josm/plugins/easypresets
ant clean
ant dist
```

  - フォルダ'`~/workspace/josm/dist/`'に、`easypresets.jar`が生成される


### (3-2) [easypresets]のビルド（Eclipse編）

- 'Eclipse' → プロジェクト[`josm`]-[`plugins`]-[`easypresets`]を右クリック

  - → [`プロジェクトのビルド...`]を選択

- フォルダ'`~/workspace/josm/dist/`'に、`easypresets.jar`が生成される


## (4) [easypresets.jar]をデプロイ

「JOSM」は`(ユーザホーム)/.josm/plugins/`'にあるプラグインをロードしようとするので、生成された`easypresets.jar`を実行するには、フォルダ'`(ユーザホーム)/.josm/plugins/`'に、`easypresets.jar`を配置する必要がある

![dev2_deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/dd3752d1-c7e6-53e3-5311-159f25d9d4b9.png)


- フォルダ'`~/.josm/plugins/`'に、`easypresets.jar`をコピーする

	```
	cp ~/workspace/josm/dist/easypresets.jar ~/.josm/plugins/
	```


## (5) プラグインの実行

いよいよ実行してみる

ただ実行しただけではつまらないのでブレークポイントを設定してみる

プラグインの開始地点にブレークポイントを設定してみる、プラグインの開始地点は`org.openstreetmap.josm.plugins.Plugin`を extend したクラスのコンストラクタだから、

「EasyPresets」の場合には、クラス`org.maripo.josm.easypresets.EasyPresetsPlugin` になる

- コンストラクタ`EasyPresetsPlugin()`の`super(info)`にブレークポイントを設定してみる<br/>![step2_010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/bf735f08-269a-839c-c9fc-201bf0869399.png)

- (5-1) プロジェクト「josm」を右クリック → [デバッグ(D)] → [Javaアプリケーション]<br/>![step2_012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/0cf1902f-3082-eb6e-c601-df9b5dcec61b.png)
  - '一致する項目(M)': [`MainApplication - org.openstreetmap.josm.gui`]
  - [OK]

「josm」が起動する

- (5-2) 「JOSMメニュー」 → 「`プリセット`」 → 「`Preset preferences...`」
  - [`プラグイン`]<br/>![step2_014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/a44d842b-314c-fee8-d718-03d9ca0cc6a7.png)
    - [`OFF`] '`EasyPresets`:' ... "これはJOSMから提供された公式`EasyPresets`プラグイン"
    - [`ON`] '`easypresets`:' ... "こちらが開発中の`EasyPresets`プラグイン"
    - [`OK`]
  - JOSMを「再起動」する
  - 「再起動」しても起動されないので、プロジェクト「josm」を右クリック → [デバッグ(D)] → [Javaアプリケーション] を再実行する

- (5-3) ブレークポイントで止まる<br/>![step2_015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25141/6e05f78d-c170-8fc5-e5a6-c527e9183ade.png)

ブレークポイントで止まっただろうか？

ここまでくればあとはなんとかなるだろう

では、エンジョイ・プログラミング！！