torutkのブログ

ソフトウェア・エンジニアのブログ

Java読書会BOF「Java 11 and 12 New Features」(洋書)を読む会を開催して

Java 11 and 12 New Features」(洋書)を読む会を開催

昨日6月15日(土)に、Java読書会BOFは書籍「Java 11 and 12 - New Features」を読む会(第1回)を開催しました。

あいにくの雨模様でしたが、10名を超える参加者が集まりました。Javaの最新技術、といっても2年前の2017年にリリースされたJava SE9からの技術を解説した日本語の書籍が皆無で、洋書の選択となりました。

Java読書会BOFが開催する読書会では、書籍を本文、脚注、ソースコードとすべてを朗読して進めています。今回は洋書なので、どう進めようか?と思いましたが、英語のままで朗読して進めてみることとしました。

書籍の入手に関して

Amazonのサイトには、紙の書籍とKindle電子書籍版があり、紙版も2日程度で入手可能となっています。また、洋書の出版社Packt Publishingのサイトには、ePubおよびPDFの電子書籍版があります。Kindle版は2840円ですが、ePubおよびPDF版は10ドル(約1100円)と半額以下です。

英語の朗読について

英語の朗読なので、英語の得意な人は問題なく把握できますが、そうでないと分からない単語が多く読み取ることがなかなかむずかしいというところがありました。今回の本は割とやさしい英文でしたが、それでもちょっと苦労はあったようです。

少し時間がかかりますが、段落ごとに内容を日本語で簡単にまとめるといったフェーズをおくのがよかったかもしれません。

内容について

型推論

Java 10で導入された型推論(var)について、3時間はじっくりとかけて読みました。
ローカル変数のみ型をvarとして宣言可能で、未初期化、null代入、配列初期化子、配列の括弧とは一緒に定義できないという制約があります。また、varは予約語(キーワード)ではないので、メソッド名やインスタンス変数、static変数の識別子にvarの名前を使用可能です。

議論はありましたが、ローカル変数の宣言行でvarによる型推論を使うことでその宣言行を読んだだけでは型が分からない場合(例を次に示す)はvarによる型推論を使わない、というのが必須と思います。

var i = getData();

これは、getDataのメソッド名の宣言行(シグニチャ)を調べないと、ローカル変数iの型が分かりません。varを導入したことによりコードの読み手に対する情報が欠落してしまっています。

左辺の変数名、あるいは右辺のメソッド名から型が容易に推測できる場合はvarによる型推論を使ってもよいという意見もあります。しかし、個人的には、ローカル変数の宣言行で、型名を2回記述しなければならないときに型指定をvarとしてもよい、それ以外の場合は、型を書くというのをベストプラクティスにしたいです。

CDS(クラス・データ・シェアリング)

CDSは実はJava SE 5.0 から搭載されていた機能でしたが、まったく気にしたことがなく、使い方の記述を日本語では殆ど見かけたことがありませんでした。今回読書会では、JDKの標準クラスが格納されたclasses.jsaと、アプリケーションの起動時に必要なクラスをシェアリング用ファイルとして生成し使用するAppCDSとについて、じっくり読んで知識を得られました。

自宅のPC(Windows OS 64bit)にインストールしているJDKの各ディストリビューションとバージョンについてclasses.jsaの有無を見てみると、

  • Oracle JDK 8/9/10 ⇒ あり
  • Oracle OpenJDK 11/12 ⇒ あり
  • Liberica JDK 11 ⇒ なし
  • ZuluFX 11 ⇒ なし

となっていました。classes.jsaがない場合は、次のコマンドで生成することができます。

java -Xshare:dump 

Java SE 11以降では、CDSの使用可否を指定するJVMオプション -Xshare=auto がデフォルトとなりました。
[JDK-8197967] Make -Xshare:auto the default for server VM - Java Bug System

なので、Oracle JDK または Oracle OpenJDK の11以降を使う場合は明示的に指定しなくてもCDSが有効となります。Oracle以外のOpenJDKでclasses.jsaファイルがない場合は、そのOpenJDKのインストール直後に java -Xshare:dump を一度実行しておくとよいでしょう。

AppCDS(アプリケーション・クラス・データ・シェアリング)

CDSJavaの標準クラスをシェアする機構に対して、AppCDSはアプリケーションのクラスを含んだクラスをシェアする機構です。

オプションの指定がJava SE 11以降とJava SE 10とで変わるので少々混乱してしまいます。
次のJVMオプションはJava SE 11以降では廃止となって指定する必要はありません。

-XX:+UseAppCDS 

Java SE 11以降では、次のステップでAppCDSのシェアドアーカイブファイルを適用します。

  • 次のJVMオプションを指定してアプリケーションを実行、起動時にロードするクラス一覧のリストファイルを生成
 -Xshare:off -XX:DumpLoadedClassList=<リストファイル名>
  • 次のJVMオプションを指定してアプリケーションを実行、アプリケーションのクラスを含む起動時にロードするシェアドアーカイブファイルを生成
-Xshare:dump -XX:SharedClassListFile=<リストファイル名> -XX:SharedArchiveFile=<シェアドアーカイブファイル名> 
  • 以後、アプリケーションを実行するときは次のJVMオプションを指定
-XX:SharedArchiveFile=<シェアドアーカイブファイル名>

最初のステップで-Xshare:offを指定するのは、リストを作成するときに標準CDSアーカイブファイルから読み込むことを抑制するためと思われます。

次回の範囲は

次回は、次の項目を読み進める予定です。

  • Parallel full GC for G1
  • Miscellaneous Improvements in JDK 10
  • Local Variable Syntax of Lambda Parameters
  • Epsilon GC
  • The HTTP Client API

JavaFXの入力部品でエラー時に色を変える

GUIでユーザーが入力した値が範囲外などのエラー時に、エラーとなった箇所が分かるよう色を変える方法を模索しました。今回はTextFieldを題材とします。

CSSの疑似クラスでエラーを定義

JavaFXで、CSSファイルを使って見栄えを定義している場合、CSSファイルにTextFieldの疑似クラスerrorを次のように定義します。

.text-field:error {
    -fx-text-box-border: red;
    -fx-focus-color: red;
}
  • "-fx-text-box-border"は、TextFieldにフォーカスが当たっていないときの枠の色を指定
  • "-fx-focus-color"は、TextFieldにフォーカスが当たっているときの枠の色を指定

Javaのコードで、テキストフィールドの個々のインスタンスに疑似クラスの状態を指定

    @FXML
    private TextField myTextField;
    private PseudoClass errorClass = PseudoClass.getPseudoClass("error");
    :
    void handleSubmit(ActionEvent event) {
        if (! validateInput()) {
            myTextField.pseudoClassStateChanged(errorClass, true);
        } else {
            myTextField.pseudoClassStateChanged(errorClass, false);
        }
        :
    }

疑似クラスの名前でPseudoClassインスタンスを取得し、対象となるTextFieldインスタンスのpseudoClassStateChangedメソッドで引数に疑似クラスのインスタンスと有効・無効のフラグを指定すると見栄えを変更することができます。

この実装では、submitボタンが押された段階でTextFieldの内容をチェックし疑似クラスerrorの適不適を切り替えています。
より本格的に、TextFieldに文字を入力する度にチェックし色を変えることもできますが、本日は割愛します。

Javaプログラムへの初期設定の与え方を悩む

Javaプログラムに初期設定を外部から渡す方法として、プログラム起動時のコマンドラインオプション、設定ファイル、システムプロパティ、リソースバンドル、プリファレンスAPIjava.util.pref)辺りが候補に挙がります。
今回、PCからシリアル通信でセンサー機器と通信し、センサー機器の状態をGUIで表示するスタンドアロンプログラムを作成しています。プログラムの構造は、GUIに纏わる部分、シリアル通信に纏わる部分とを疎結合しています。ここで、疎結合ゆえにプログラムの初期設定をどのように渡すかを悩むこととなりました。

候補となる方法

コマンドライン引数

GUIJavaFXで作成しています。JavaFXコマンドラインを解析し、JavaFXのParametersクラスにキー・バリュー形式で保持する仕組みを持っています。しかし、このParametersクラスをシリアル通信部分に渡してしまうと、シリアル通信部分がJavaFXのライブラリへ依存してしまい、結合を疎にする観点では後退してしまいます。

設定ファイル

プログラムの起動時に所定のパスにあるProperties形式の設定ファイルを読み込み、これを参照する方法であれば、Java SEの標準APIjava.util.Properties)への依存で済むので、疎結合をそれなりには保てます。しかし、設定ファイルから生成したPropertiesインスタンスGUIの各所とシリアル通信の各所に持ち回す必要が生じます。
JavaFXでは、通常上位のApplication派生クラスからコントローラクラスへは直接参照を持たないので、プロパティを渡すためにコントローラーの参照を取得するコードをApplication派生クラスに追加し、またコントローラーにはプロパティを渡すメソッドを追加し、コントローラーからさらに各クラスに渡すといった持ちまわしが生じます。
シリアル通信においても、そのプロパティを各クラスに渡す持ちまわしが生じます。
この持ちまわしを避けるとしたら、プロパティをシングルトンで実装するといったプログラム全体のグローバル参照が発生します。
今回は小さなプログラムなので、1つのプロパティでもそう煩雑にはなりませんが、大きなプログラムになると、1つのプロパティに数百個以上のキー・バリュー定義が格納されることになり、あまり望ましい姿ではありません。

システムプロパティ

Java起動時のコマンドラインJVMオプション)でシステムプロパティを定義することができます。
システムプロパティは、Java SE標準のAPIjava.lang.SystemクラスのgetPropertyメソッド)で取得できるので、疎結合の点で問題はなく、持ちまわしも不要ですが、多数の項目があるとJava起動時のコマンドラインが膨大となってしまいます。

リソースバンドル

Javaには、主に国際化対応の仕組みとしてロケールに応じて切り替える文字列等のリソースをプロパティファイルまたはクラスに切り出し、実行時にロケールに応じたファイルを読み込むリソースバンドルの仕組みがあります。このファイルに初期設定を書く方法がありますが、リソースファイルは通常JARファイルの中に収められるので、インストール後に設定を変更する場合、JARから取り出し修正したファイルを再度JARに戻すという手順が必要になり、これも好ましくありません。また、リソースバンドルは主にGUIの表示で使うので、シリアル通信などGUIから切り離した内容を記述するのは不適切と思われます。

プリファレンスAPI

Javaには、プリファレンスAPIjava.util.prefs)があり、ユーザー毎に異なる設定を保存・読み出して使用することと、ユーザー共通の設定を保存・読み出して使用することができます。
これはJava SE標準APIなのでシリアル通信からJavaFXへの依存はなくて済みます。
プリファレンスAPIを通して設定する内容は、Windows OSの場合はレジストリに格納され、UNIX系OSの場合はユーザー毎の設定はユーザーのホームディレクトリ下のファイルに、ユーザー共通の設定はシステムで一意の場所にファイルで置かれます。
レジストリやファイルは、プログラムをインストールして最初にプリファレンスを保存するまで生成されないので、インストール直後から初期設定を置くにはプリファレンスAPIを使って保存操作を最初にする必要があります。また、実行するユーザーの権限ではユーザー共通の設定を書き込むことができないことがあります(通常このケースが多いかと)。プリファレンス設定ツールが必要になるかもしれません。

結局どれにしよう?

用途によりトレードオフすることとなりそうです。

Java読書会BOFは6月から「Java 11 and 12 - New Features」を読み始めます

Java読書会BOFは、6月から新しい書籍「Java 11 and 12 - New Features」(洋書)を読み始めます。

Java SE 9が2017年9月にリリース後、この2019年5月末時点までに、Java SE 10(2018年3月)、Java SE 11(2018年9月)、Java SE 12(2019年3月)とリリースされ、Java SE 11については、長期間サポート版(LTS: Long Term Support)となっています。

ところが、この2年内のJavaのアップデートについてしっかり書かれた日本語書籍はほとんどなく、洋書で勉強するとなった次第です。

Java読書会BOFでは、過去洋書を扱ったときは事前に分担を決め日本語訳をして、それを当日配布して日本語訳を朗読するという方法を取ってきました。
これは、精読できるのですが事前の準備負担が大きいので対応し難くなっています。今回は、事前訳はせずにその場で粗い日本語で朗読を進めようかと思っています。

さて、今回の書籍の章題を列挙すると次になります。

  • 型推論(Type Inference)
  • アプリケーション・クラス・データ共有(Application Class-Data Sharing: AppCDC)
  • ガーベージコレクター最適化(Garbage Collector Optimizations)
  • JDK 10の細々な改善(Miscellaneous Improvements in JDK 10)
  • ラムダ式の引数のローカル変数文法(Local Variable Syntax for Lambda Parameters)
  • イプシロンGC(Epsilon GC
  • HTTPクライアントAPI(The HTTP Client API
  • ZGC
  • フライトレコーダーとミッションコントロール(Flight Recorder and Mission Control)
  • JDK 11の細々な改善(Miscellaneous Improvements in JDK 11)
  • switch式(Switch Expressions)
  • JDK 12の細々な改善(Miscellaneous Improvements in JDK 12)
  • プロジェクトAmberにおける列挙型の改善(Enhanced Enums in Project Amber)
  • データクラスとその使用(Data Classes and Their Usage)
  • 生文字列リテラル(Raw String Literals)
  • ラムダの食べ残し(Lambda Leftovers)
  • パターンマッチング(Pattern Matching)

JDKの新しい機能としてちらっと見聞きしたことのある、でも良くわからない機能が並んでいます。
今回の読書会を通じて、これらの新機能について一定の理解をしておくことができるのはなかなかに期待度が高いです。

今月のJava読書会は、6月15日(土)に川崎駅近くで開催します。

Java読書会6月からの本の投票

Java読書会BOFの書籍選定

Java読書会BOFでは、月1回の読書会を開催しており、5月で「Effective Java第3版」をほぼ読了し、6月からは新しい本の読書会を開始します。現在読書会のWebサイトでWeb投票実施中(5月26日〆切)です。

Javaの技術動向は変化が大きくなってきている

Javaは、2017年9月に Java SE 9がリリースされ、そこではModule Systemが導入されています。また、Java SE 9以降はこれまでの2~3年に1回のメジャーバージョンアップをリリースする形態から、半年毎にメジャーバージョンアップをリリースする形態に変更され、新機能が早い段階でリリースされ利用可能になっています。2018年3月にJava SE 10、2018年9月にJava SE 11、2019年3月にJava SE 12と半年毎にバージョンアップされています。

一方で安定的に利用したいユーザー向けには3年に1回、長期サポート版(LTS)を提供するようになりました。最初のLTS版は、2018年9月のJava SE 11です。これは少なくとも次のLTS版まで(則ち最低3年間)はセキュリティパッチを含む修正版が提供されます。LTS版以外は、次のバージョンがリリースされるまでの間(則ち半年間)だけは修正版が提供されます。

余談、有償化騒ぎについて

このLTS版については、Oracleが提供するOracle JDKについては商用利用(個人利用および商用利用でも開発・試験・デモは除く)が有償となっているので、すわJavaが有償化だと一部で騒ぎになっていました。しかし、Javaはずいぶん前からオープンソース開発(OpenJDK)となっており、特に最初のLTS版であるJava SE 11ではOracle JDKに搭載されていた商用機能(Flight Recorder等)がOpenJDKに搭載され、Oracle以外にもいくつかの組織からLTS版が無償提供されています。

読書会で読みたい本が・・・

このようにJavaの進化は短い時間で次々行われてきていますが、日本語での書籍でJava SE 9以降の新しい機能を詳しく解説しているものはほとんど出版されていません。

となると、Javaの新しい技術を読みたいとすると洋書を選択することになります。過去読書会でも幾度か洋書を読んできたので、それほど敷居が高いということはありませんが、洋書ウォッチャーが少ないのでこれぞという本を選ぶのが大変です。

Java Platform Module System(JPMS)の本

Java SE 9で導入され、なかなか骨のある(移行が大変、理解が大変)割にプログラミングの改善にはあまり寄与していない(APIの実装隠蔽や、ソフトウェアのライフサイクル上はとても重要な)技術がJPMSではないでしょうか。

JPMSを扱った書籍を調べてみると、次が見つかりました。

最初の本はまだ未完です。2番目以降はJava SE 9リリース時期(2年前)に出版されているので、ちょっと古いなというのと、ページ数がやや多いが難です。
(洋書の読書会の場合、事前に粗く訳してくるので、ページ数が多いとそれだけ大変)

ということで、JPMS本は今回は推薦せずにおこうかと思います。

さくらVPSのOS更新

さくらVPSのOSをCentOS 6からCentOS 7へ更新

さくらVPSのサーバーは利用開始時から長らくCentOS 6でしたが、このGWで時間が取れたのでやっとCentOS 7へ更新してみました。

OSの再インストールをするので、データのバックアップ、設定のバックアップを取ってから作業に着手します。Let's EncryptのSSL証明書(無料)を利用していたので、再インストール時には、スタートアップスクリプトとして用意されているLetsEncryptを追加しています。

とくに問題なくCentOS 7になりました。IPv6が無効なので有効にして、root以外の作業用アカウントを作成し、SSHポートを標準から変更し、rootのsshログインを無効にしました。

Redmineの稼働にむけて

Ruby 2.4のインストール

RedmineはOS更新前はバージョン3.4系で稼働していましたが、そろそろ4.0系も動かしたいところです。Redmine 4.0は、Ruby on Rails 5.2を用いているため、rubyのバージョンは2.2.2以降となります。しかし、CentOS 7の標準rubyは2.0のため、rubyを別途更新する必要があります。

rubyenvは開発者個人の環境で使うのはまだしも本番環境で使うには気持ち悪いので、以前は自前でRPMビルドしていました。

今回は手元にCentOS 7環境がないので、他の手段を探してみたところ、Red Hat Software Collections というyumリポジトリRed Hatから提供されており、これを利用するのがよさそうです。

$ sudo yum install centos-release-scl-rh 

rubyについては、rh-ruby22、rh-ruby23、rh-ruby24、rh-ruby25とrubyの新しバージョンが用意されています。今回は、Redmine 3.4が対応する最新のrh-ruby24を入れます。

$ sudo yum install rh-ruby24

Red Hat Software Collectionsパッケージは、/opt/rh以下にインストールされます。結構パスが深いのですが、パスを通すenableというファイルが提供されているので、これを/etc/profile.d下にリンクします。

$ sudo ln -s /opt/rh/rh-ruby24/enable /etc/profile.d/rh-ruby24.sh
ruby develのインストール
$ sudo yum --enablerepo=centos-sclo-rh install rh-ruby24-ruby-devel

rubygem bundlerのインストール
$ sudo yum --enablerepo=centos-sclo-rh install rh-ruby24-rubygem-bundler
rubygem rakeのインストール
$ sudo yum --enablerepo=centos-sclo-rh install rh-ruby24-rubygem-rake
  • メモ)rakeは事前インストール不要

Development Toolsのインストール

Redmineインストール手順では、yum groupinstallでDevelopment Toolsをインストールしますが、これが次の結果となりました。

$ sudo yum groupinstall "Development Tools"
Loaded plugins: fastestmirror, langpacks
There is no installed groups file.
Maybe run: yum groups mark convert (see man yum)
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
Warning: Group development does not have any packages to install.
Maybe run: yum groups mark install (see man yum)
No packages in any requested group available to install or update

これは最初エラーかなと思いましたが、実は必要なパッケージはインストール済みであるときに出るようです。

MariaDBのインストール

最新のRedmineインストール手順(redmine.jp)は、データベースにPostgreSQLを使うものになっています。今回は、MySQLMariaDB)のダンプを使うので、MariaDBをインストールします。

$ sudo yum install mariadb-server mariadb-devel
  :

MySQL/MariaDBでutf8を指定した場合、UTF-8のうち4バイト文字を扱えません。例えば絵文字が該当します。そこで、UTF-8の4バイト文字を扱えるようにするにはutf8mb4を指定します。

/etc/my.cnf.d/server.cnf
[mysqld]
character-set-server = utf8mb4
/etc/my.cnf.d/mysql-clients.cnf
[mysql]
default-character-set = utf8mb4
show-warnings
MariaDB自動起動設定
$ sudo systemctl enable mariadb.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
mysql_secure_installation実行

セキュアな初期設定を行うツール mysql_secure_installationを実施します。ツールを実行すると次の有無を尋ねられ、基本Yesを設定していきます。

  • MariaDBのrootユーザーのパスワードを設定
  • 匿名ユーザーを削除
  • MariaDBのrootユーザーのリモート接続禁止
  • testデータベースとそのアクセス設定を削除
redmineのユーザーアカウントとデータベース作成
$ mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE redmine CHARACTER SET utf8mb4;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> CREATE USER 'redmine'@'localhost' IDENTIFIED BY '********';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';
Query OK, 0 rows affected (0.00 sec)

ImageMagickのインストール

$ sudo yum install ImageMagick ImageMagick-devel ipa-pgothic-fonts
  :

Redmine実行ユーザー作成

Redmineを実行する際、root権限ではなくredmine実行ユーザー権限とします。

$ sudo groupadd -g 1000 redmine
$ sudo useradd -u 1000 -g redmine redmine
$ sudo passwd redmine
  :

Redmineのダウンロード

$ sudo mkdir /var/lib/redmine-3.4-stable
$ sudo chwon redmine:redmine /var/lib/redmine-3.4-stable
$ su redmine
$ cd /var/lib
$ svn co http://svn.redmine.org/redmine/branches/3.4-stable redmine-3.4-stable
  : 

database.ymlの作成

production:
  adapter: mysql2
  database: redmine
  host: localhost
  username: redmine
  password: "********"
  encoding: utf8mb4

configuration.ymlの作成

production:
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "localhost"
      port: 25


imagemagick_convert_command: /usr/bin/convert
rmagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf

Redmineが依存するgemパッケージのインストール

$ bundle install --without development test --path vendor/bundle
  :

セッション秘密鍵生成

$ bundle exec rake generate_secret_token

バックアップしたデータベースを復元

$ mysql -uredmine -p redmine < /tmp/redmine_mysql_www.torutk.com-20190430T110540.dump
Enter password:********
データベースのマイグレート
$ RAILS_ENV=production bundle exec rake db:migrate

unicornのインストール

Gemfile.local新規作成
  • /var/lib/redmine-3.4-stable/Gemfile.local
gem "unicorn"
gemパッケージのunicornインストール
$ bundle update
unicorn.rb

動作確認
$ bundle exec unicorn_rails -c config/unicorn.rb -E production

エラー発生

I, [2019-04-30T21:28:36.880592 #27919]  INFO -- : Refreshing Gem list
ArgumentError: wrong number of arguments (given 0, expected 2)
  /var/lib/redmine-3.4-stable/vendor/bundle/ruby/2.4.0/gems/unicorn-5.5.0/lib/unicorn.rb:49:in `block in builder'

unicorn 5.5.0だと発生するとのこと。
stackoverflow.com

unicorn 5.4.1で止めおくのが回避策とあるので、

redmine-unicorn.service
[Unit]
Description=Redmine Unicorn Server
After=mariadb.service

[Service]
WorkingDirectory=/var/lib/redmine
Environment=RAILS_ENV=production
SyslogIdentifier=redmine-unicorn
PIDFile=/var/lib/redmine/tmp/pids/unicorn.pid

ExecStart=/opt/rh/rh-ruby24/root/bin/bundle exec "unicorn_rails -c config/unicorn.rb -E production"
ExecStop=/usr/bin/kill -QUIT $MAINPID
ExecReload=/bin/kill -USR2 $MAINPID

User=redmine
Group=redmine

[Install]
WantedBy=multi-user.target

実行するとエラー

$ sudo systemctl start redmine-unicorn.service

原因を調べるため、suコマンドでユーザーを切り替えてunicornを実行するとエラーとなりました。
エラー内容は

/opt/rh/rh-ruby24/root/usr/bin/ruby: error while loading shared libraries: libruby.so.2.4: cannot open shared object file: No such file or directory

suコマンドで(-なしに)ユーザーを切り替える場合は、profile.dの設定を読み込まないので、rubyのパスが参照できないためです。
これは、systemdで実行ユーザーを指定して実行する場合と同じと考えられます。

systemdのunitファイル記述では、EnvironmentFile指定が可能ですが、このファイル内では変数展開ができないため、先に設置した/etc/profile.d/rh-ruby24.shを指定することができません。

回避策として、実行コマンドをsclコマンドで指定します。

  • /usr/lib/systemd/system/redmine-unicorn.service (修正箇所)
ExecStart=/usr/bin/scl enable rh-ruby24 -- bash -c 'bundle exec unicorn_rails -c config/unicorn.rb -E production'

Red Hat Software Collectionsのコマンドsclを使ってコマンドを実行すると、必要な環境設定が反映されます。

nginxとの連携

  • バックアップしていたredmine.confを/etc/nginx/conf.d/に配置
  • /etc/nginx/conf.d/default.confを削除、空のdefault.confに置き換え
  • /etc/nginx/conf.d/https.confを削除、空のhttpd.confに置き換え

nginxのアップデート時にdefault.confとhttps.confが生成されないよう、削除だけではなく空のファイルを置いておきます。

テーマのインストール

gitmike
$ cd /var/lib/redmine/public/themes
$ git clone git://github.com/makotokw/redmine-theme-gitmike.git gitmike

プラグインのインストール

$ cd /var/lib/redmine/plugins
Issue Template

現時点でmasterブランチはredmine 4.0以降のみ対応となっています。redmine 3.xで使うときは、ブランチ名にv0.2.x-support-Redmine3 を指定します。

$ git clone -b v0.2.x-support-Redmine3 https://github.com/akiko-pusu/redmine_issue_templates.git
Banner

現時点でmasterブランチはredmine 4.0以降のみ対応となっています。redmine 3.xで使うときは、ブランチ名にv0.1.x-support-Redmine3 を指定します。

$ git clone -b v0.1.x-support-Redmine3 https://github.com/akiko-pusu/redmine_banner.git
Wiki Extensions

現時点で存在するブランチdevelopおよびmasterはともにredmine 4.0以降のみ対応となっています。redmine 3.xで使うときは、タグ名に0.8.2を指定します。

$ git clone https://github.com/haru/redmine_wiki_extensions
XLS Export
$ git clone https://github.com/two-pack/redmine_xls_export.git
$ bundle install

gemパッケージのspreadsheet を必要とするので、bundle installを実行します。

Clipboard Image Paste
$ git clone https://github.com/peclik/clipboard_image_paste.git
Wiki Lists
$ git clone https://github.com/tkusukawa/redmine_wiki_lists.git
LaTeX MathJax Macro
$ git clone https://github.com/mboratko/redmine_latex_mathjax.git
$ bundle install
  • gemパッケージのrender_parentを必要とするので、bundle installを実行します。
Sidebar Hide
$ git clone https://gitlab.com/bdemirkir/sidebar_hide.git
Glossary
$ git clone https://github.com/torutk/redmine_glossary.git
Github hook
$ git clone https://github.com/koppen/redmine_github_hook.git

設定の復旧は後日実施。

View Customize
$ git clone https://github.com/onozaty/redmine-view-customize.git view_customize
$ bundle install
  • ディレクトリ名はview_customizeでないといけない
  • gemパッケージのactiverecord-compatible_legacy_migrationを必要とするので、bundle installを実行します
Startpage
$ git clone https://github.com/gatATAC/redmine_startpage.git

添付ファイルの復元

バックアップを取っていたマシンからrsyncで転送します。

リポジトリSVN、Git)の復元

SVNは、ダンプファイルをインポートします。
Gitは、git clone --mirror でクローンしたリポジトリから配置したい場所へpushします。

NginxからUnicorn使用

Nginxの設定ファイルを戻します。

およそ復元完了

4月30日の昼頃から作業を開始して、5月1日の昼頃までかかってしまいました。
平成のうちには更新が終わらなかったです。

次はRedmine 4.0へのアップデートをする予定です。

GPSの高度と標高

GPSの高度と標高

GPSを使った測位では、地球を回転楕円体(WGS84回転楕円体)としたときの緯度・経度および高度を取得します。

ここで、GPS測位で得られる高度は回転楕円体面からの距離として算出されるので、実際の標高(海面からの距離)とは異なります。回転楕円体の表面と海面(ジオイド面)とは場所によりおよそプラスマイナス100mの範囲で差異があります。

東京付近では、回転楕円体表面から40mほど高い位置にジオイド面があります。したがって、GPSの高度から40mを減算すると標高(日本の標高は、東京湾の平均海面を0mとしたときの高さ)となります。

ジオイド高は、国土地理院ジオイド高計算サイトで計算させることができます。
https://vldb.gsi.go.jp/sokuchi/surveycalc/geoid/calcgh/calcframe.html