renderd から Mapnik を使うときに 「no datasource plugin directories have been successfully registered」 って言われる問題
背景
renderd (mod_tile から使われるマルチスレッドのプロセス) から Mapnik を使って地図タイルをレンダリングしようとしている。
Linux ディストリビューションとして Ubuntu 18.04 を使用して、renderd は APT リポジトリ ppa:osmadmins/ppa の renderd パッケージを使用。 Mapnik もこのパッケージの依存パッケージ (libmapnik3.0) としてインストールされる。
上記パッケージで renderd をインストールした場合に自動的に生成される設定ファイルは /etc/renderd.conf に置かれ、その内容は下記のようになっている。
[renderd] stats_file=/var/run/renderd/renderd.stats socketname=/var/run/renderd/renderd.sock num_threads=4 tile_dir=/var/lib/mod_tile [mapnik] plugins_dir=/usr/lib/mapnik/2.0/input font_dir=/usr/share/fonts/truetype/ttf-dejavu font_dir_recurse=false [default] URI=/osm/ XML=/etc/mapnik-osm-data/osm.xml DESCRIPTION=This is the standard osm mapnik style ;ATTRIBUTION=©<a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a> and <a href=\"http://wiki.openstreetmap.org/w\ iki/Contributors\">contributors</a>, <a href=\"http://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA</a> ;HOST=tile.openstreetmap.org ;SERVER_ALIAS=http://a.tile.openstreetmap.org ;SERVER_ALIAS=http://b.tile.openstreetmap.org ;HTCPHOST=proxy.openstreetmap.org
遭遇した問題 : エラーが発生する
renderd のプロセスを起動した後、下記のようなエラーが発生していた。
An error occurred while loading the map layer 'ajt': Could not create datasource for type: 'shape' (no datasource plugin directories have been successfully registered) encountered during parsing of layer 'ocean-lz' in Layer at line 269 of '/home/renderaccount/src/openstreetmap-carto/mapnik.xml'
とか
An error occurred while loading the map layer 'ajt': Could not create datasource for type: 'postgis' (no datasource plugin directories have been successfully registered) encountered during parsing of layer 'landcover-low-zoom' in Layer at line 755 of '/home/renderaccount/src/openstreetmap-carto/mapnik.xml'
調べたこと
- Mapnik はプラグインアーキテクチャを採用している (参考 : PluginArchitecture · mapnik/mapnik Wiki)
- renderd から Mapnik を使うときには、renderd の設定ファイルに Mapnik の設定も記述する。
- 参考 : mod_tile/renderd.conf at master · openstreetmap/mod_tile · GitHub (
[mapnik]
と書かれている部分) - Mapnik のプラグインディレクトリもこのファイルで指定する。 (
plugins_dir=/usr/lib/mapnik/input
みたいなやつ)
- 参考 : mod_tile/renderd.conf at master · openstreetmap/mod_tile · GitHub (
- libmapnik3.0 パッケージのファイル一覧を見るとわかるように、/usr/lib/mapnik3.0/input がプラグインのディレクトリ
読んだ : JUnit 実践入門 〜 体系的に学ぶユニットテストの技法
JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)
- 作者: 渡辺修司
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/21
- メディア: 単行本(ソフトカバー)
- 購入: 14人 クリック: 273回
- この商品を含むブログ (69件) を見る
既に JUnit 5 が出ているし今更感はある (本書は JUnit 4 を題材にしている) けど、テストの全体的な話も学べるかなって思って読んだ。 JUnit 4 の話もありつつテスト全般に関する知見も書かれているので、(類書も少ないので) 読む機会がある人はさらっと読んでみるといいかもしれない。
新しく学んだこと
テスト全般
- テストフィクスチャ (test fixtures) : テストの対象やテストの入力値や検証用の値、外部リソースなどの実行環境やテストの実行前に必要なオブジェクトの操作などのこと。
- 狭義にはテストデータだけを指して 「テストフィクスチャ」 と呼ぶこともあるらしい。
- 振舞駆動開発 (behavior driven development; BDD) : ソフトウェアの相互作用に着目してソフトウェアがどのように振る舞うかを定義することを起点とした開発技法
JUnit 4 について
Theories
ランナーでパラメータ化テストができる。- Cucumber / cucumber-junit で振舞駆動開発を実現できる。
docker build 時の apt install が遅い問題 (docker build の --add-host オプションを使って APT のパッケージリポジトリを国内ミラーに設定できる)
こんにちは、Docker ビルドおじさんです。
今日ずっと docker build してる (してない)
— Nobuoka Yu (@nobuoka) 2019年3月22日
ubuntu:18.04
ベースで Dockerfile を書いてビルドしまくってるのですが、apt install
がとにかく遅い!!! なぜなら日本に住んでいるから!! archive.ubuntu.com が遠い!!!
Dockerfile に追記せずに apt で使うリポジトリを https://t.co/Skrw55Kyjw から国内のミラーに変える技みたいなのないんだろうか……
— Nobuoka Yu (@nobuoka) 2019年3月22日
解決方法
調べてみたらいろいろ解決策がありそうだった。
解決策 その 1
日本を出る。 archive.ubuntu.com の近くに行きましょう。
解決策 その 2
Dockerfile をいじって (一時的にでも) APT のパッケージリポジトリの URL を国内ミラーに変更する。 「apt docker 遅い」 みたいなキーワードで検索するとこの方法がひっかかる。
解決策 その 3
apt-cacher みたいなやつでキャッシュしたり、Squid による透過型プロキシでキャッシュしたりする。 わりとこれが素直な方法な気もするが、ちょっと大変そうな気もする。
解決策 その 4
この記事で共有したいのはこの方法。 docker build
コマンドの --add-host
オプションを使って APT のリポジトリのホスト名に対応する IP アドレスを書き換えちゃう方法。
そういう感じしかないのかなー、って思ってたんですが、調べてみたら `docker build` に `--add-host` オプションがあるからこれが使えるのでは?? ってなってます (試してみます) https://t.co/5nMTjn2efn
— Nobuoka Yu (@nobuoka) 2019年3月22日
例えば ubuntu:18.04
をベースとするイメージの場合、リポジトリのホスト名として archive.ubuntu.com などが使われていて、国内ミラーは jp.archive.ubuntu.com となっているので、nslookup jp.archive.ubuntu.com
で国内ミラーの IP アドレスを調べて、docker build --add-host="archive.ubuntu.com:xxx.xxx.xx.xx" .
という感じで国内ミラーの IP アドレスを指定してやると良さそう。
セキュリティ的なところはちょっと気になる。
まあセキュリティ的にはちょっと気になるところではありますよね。 手元で試行錯誤するときに apt install を早くしたい、みたいな時に設定すると良さそうです!
— Nobuoka Yu (@nobuoka) 2019年3月22日
Ubuntu では ca-certificates パッケージで CA 証明書をインストールできるぞ
1 行まとめ
Ubuntu ベースの Docker コンテナで SSL 接続をするために ca-certificates
パッケージをインストールしましょう。
エラー内容
Ubuntu 18.04 (ubuntu:18.04
) ベースの Docker コンテナで HTTPS 接続ができなくて npm install に失敗した。
root@068c8e545fca:/# npm install -g carto npm ERR! Linux 4.9.125-linuxkit npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "carto" npm ERR! node v8.10.0 npm ERR! npm v3.5.2 npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY npm ERR! unable to get local issuer certificate npm ERR! npm ERR! If you need help, you may report this error at: npm ERR! <https://github.com/npm/npm/issues> npm ERR! Please include the following file with any support request: npm ERR! /npm-debug.log
見るからに CA 証明書のエラーっぽい。 /npm-debug.log の中身を見ると以下のような感じ。
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'install', '-g', 'carto' ]
(略)
15 info attempt registry request try #1 at 10:34:44 AM
16 verbose request id 454780186dc942d1
17 http request GET https://registry.npmjs.org/carto
18 info retry will retry, error on last attempt: Error: unable to get local issuer certificate
19 info attempt registry request try #2 at 10:34:54 AM
20 http request GET https://registry.npmjs.org/carto
21 info retry will retry, error on last attempt: Error: unable to get local issuer certificate
22 info attempt registry request try #3 at 10:35:54 AM
23 http request GET https://registry.npmjs.org/carto
24 silly fetchPackageMetaData Error: unable to get local issuer certificate
24 silly fetchPackageMetaData at TLSSocket.(_tls_wrap.js:1105:38)
24 silly fetchPackageMetaData at emitNone (events.js:106:13)
24 silly fetchPackageMetaData at TLSSocket.emit (events.js:208:7)
24 silly fetchPackageMetaData at TLSSocket._finishInit (_tls_wrap.js:639:8)
24 silly fetchPackageMetaData at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
24 silly fetchPackageMetaData error for carto { Error: unable to get local issuer certificate
24 silly fetchPackageMetaData at TLSSocket.(_tls_wrap.js:1105:38)
24 silly fetchPackageMetaData at emitNone (events.js:106:13)
24 silly fetchPackageMetaData at TLSSocket.emit (events.js:208:7)
24 silly fetchPackageMetaData at TLSSocket._finishInit (_tls_wrap.js:639:8)
24 silly fetchPackageMetaData at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38) code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' }
(略)
30 verbose stack Error: unable to get local issuer certificate
30 verbose stack at TLSSocket.(_tls_wrap.js:1105:38)
30 verbose stack at emitNone (events.js:106:13)
30 verbose stack at TLSSocket.emit (events.js:208:7)
30 verbose stack at TLSSocket._finishInit (_tls_wrap.js:639:8)
30 verbose stack at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
31 verbose cwd /
32 error Linux 4.9.125-linuxkit
33 error argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "carto"
34 error node v8.10.0
35 error npm v3.5.2
36 error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
37 error unable to get local issuer certificate
38 error If you need help, you may report this error at:
38 error <https://github.com/npm/npm/issues>
39 verbose exit [ 1, true ]
curl コマンドを試してみるも、当然ながらこちらも CA 証明書のエラー。
root@068c8e545fca:/# curl https://google.com/ curl: (77) error setting certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs
原因と対応
Ubuntu では基本的な CA 証明書が ca-certificates
パッケージで提供されている。 これがインストールされていない状態で npm install
コマンドや curl
コマンドで HTTPS 通信しようとすると CA 証明書のエラーが発生する。 curl
パッケージなどをインストールする際に、デフォルトでは推奨パッケージとして ca-certificates
パッケージもインストールされるのでこのエラーには遭遇しづらいが、Docker イメージをビルドする際に apt install -y --no-install-recommends curl
という感じで --no-install-recommends
オプションを付けていると ca-certificates
パッケージがインストールされずに、上記の状態になる。
対策としては、単純に ca-certificates
パッケージをインストールすれば良い。
Java EE 技術から EE4J (Jakarta EE) 技術に移行する
2017 年に発表された Java EE の Eclipse Foundation への移管。 移管されたプロジェクトをまとめるルートプロジェクトの名前は Eclipse Enterprise for Java (EE4J) で、Java EE に相当するプラットフォームの名前は Jakarta EE となっている *1。
- EE4J プロジェクトページ : Eclipse EE4J | projects.eclipse.org
- Jakarta EE : Jakarta EE Software | Cloud Native | The Eclipse Foundation
EE4J には JAX-RS や JSON Processing (JSON-P) などの Java EE の一部として使われていたプロジェクトも移管されている。 これらを単体で使う場合も今後は EE4J のものを使っていくべきだろう。 (古いリポジトリの方は更新されないだろうので。)
EE4J 傘下になってからの最初のリリースがぼちぼちなされていたりして、そろそろ EE4J の方に移行できるようになってきているので、移行について調べたことをまとめておく。
EE4J の各プロジェクト
EE4J 傘下のプロジェクトについては EE4J プロジェクトページ からリンクがあるので、それを辿ると見つけられる。 例えば JAX-RS のページや JSON-P のページは下記である。
EE4J 各プロジェクトの Maven リポジトリ
EE4J への移管に伴って、多くのプロジェクトの API や参照実装 (Reference Implementation; RI) の Maven リポジトリのグループ ID やアーティファクト ID が変更されている。 API については下記ページにまとめられている。
見た感じでは、javax
という部分が jakarta
に変更されている模様 *2。
参照実装についてはプロジェクトごとに異なるようである。
例えば、JSON-P の参照実装については下記のように書かれており、org.glassfish:javax.json
から org.glassfish:jakarta.json
に変更されていることがわかる。
The main API jar file is now located at jakarta.json:jakarta.json-api and the main RI jar file is now located at org.glassfish:jakarta.json.
JSON Processing (JSON-P)
一方で、JAX-RS の参照実装である Jersery については、バージョン 2.28 が最初の Jakarta EE 実装としてリリースされているが、特にグループ ID やアーティファクト ID の変更はないようである。
ソースコードの変更は必要か?
Maven アーティファクトの名前が変わってはいつつも、API 自体に変更はない。 Java EE 時代の最後の API を使っているソースコードであれば、そのまま EE4J の最初のリリースに移行できるはず。
This is common for every Jakarta EE project this release: it was required not to provide any changes in API and functionality to ensure the compatibility between last Java EE and initial Jakarta EE releases.
Jersey 2.28 has been released | Jan's Blog
*1:EE4J と Jakarta EE の名前の使い方などは Jakarta EE の FAQ に書かれている。 が、これを読んでも正直なところ EE4J と Jakarta EE の使い分けがいまいちわからない……。
*2:正式な名前変更のルールについてはどこかで言及されているのかもわからないが、見つけられていない。