JRuby 9.2.11.0でRails5アプリをwarに変換してJavaEEコンテナで運用するまで

Windows版JRuby 9.2.11.0でRails5アプリをwarに変換してJavaEEコンテナで運用するまで

タイトルの通りで、Windows版JRuby 9.2.11.0上でRails5のWebアプリを開発して、warファイルに変換してから、JavaEEコンテナ上で実行するところまでの手順を解説する。

使用した各ソフトウェアのバージョンは、
・JRuby 9.2.11.0 (Windows版)
・Rails 5.0.1
・warbler 2.05
・tomcat 8.5.1.6
である。

JRuby 9.2.11.0とRails5.0.1の導入

以下の記事を参考にして、JRuby(9.2.11.0)にRails5環境を導入していく。なお、以下の記事はRails6環境の導入記事だが、今回はwarblerとの関係でRails5環境を導入する。

Windows版JRuby 9.2.11.0環境にRails 6.0.2.2を導入する


今回はrails5を導入するため、railsの導入部分を以下のコマンドで実行する。

gem install rails -v 5.0.1

※本稿執筆時点でのRails5の最新版は”5.2.4.2 “だが、依存しているrubyzipのバージョンが2.3.0では後述するwarblerが動作しないため、rubyzipの1.X系列に依存する5.0.1を使用する。

warlberの導入

warbler2.0.5を以下のコマンドで導入する。

gem install warbler -v 2.0.5

なお、warblerのリリースは2018年5月から停止しているので、最新のRails環境に対応したwarblerのリリースは現状では期待できないだろう。。。
実際に筆者がRails6環境やRails5.2.4.2環境でwarblerを使用したところ、rubyzipのバージョンが2.3.0のため、1.X系列を使用するwarblerは使用できない旨のメッセージが出た。

Railsアプリの実装

以下のコマンドで最小限のRailsアプリを実装する。

Railsプロジェクトの作成。

rails new warsample

コントローラーの作成

cd warsample
rails generate controller test index

Railsサーバーの起動

rails s

以下のURLのアクセスしてページが表示されるかを確認する。

http://localhost:3000/test/index

warファイルの生成

以下のコマンドでRailsアプリをwarファイルに変換する。railsプロジェクトのディレクトリで以下のコマンドを実行する

warble

railsプロジェクトのディレクトリにwarsample.warファイルが生成されることを確認する。

JavaEEコンテナへのwarファイルのデプロイ

適当なJavaEEコンテナを使用してwarファイルをデプロイする。
この時、環境変数SECRET_KEY_BASEを設定しておく必要がある。

rake secret
XXXXXX(ランダムな文字列が生成される)
set SECRET_KEY_BASE=XXXXXX

JavaEEコンテナとして、筆者はapache-tomcat-8.5.16を使用した。tomcatのwebappsディレクトリにwarsample.warを配置して、以下のコマンドを実行する。

cd <tomcatのディレクトリ>/bin
catalina run

コンテナが起動したら、以下のURLにアクセスして動作することを確認する。

http://localhost:8080/warsample/test/index

これで、Rails5アプリをJavaEEで運用できることを確認した。

まとめ

JRubyで最小限のRails5アプリを実装して、JavaEEコンテナで運用することはできる。

参考文献)

JRuby徹底入門 ISBN 9784881666456

[Rails]production環境で動かす

GitHub – jruby/warbler: Warbler chirpily constructs .war files of your Ruby applications.

 

 

Windows版JRuby 9.2.11.0環境にRails 6.0.2.2を導入する

Windows版JRuby 9.2.11.0環境にRails 6.0.2.2を導入する

JRuby 9.2.11.0環境でRails 6.0.2.2を導入しようとすると色々な不具合にあった。
以下の手順を実行したところ、問題なくRails 6.0.2.2を導入できた。

  • gccが導入されていない
    各種gemパッケージのインストール時にnative-extensionの導入に失敗する。MinGWをインストールして回避
  • makeコマンドが無い
    makeコマンドが無いため、native-extenstionの導入に失敗する。
    MinGWに導入されているmingw32-make.exeを呼び出すmake.batを以下のように作成する。[make.bat]
@echo off

set BATCH_DIR=%~dp0
set BIN_DIR=%BATCH_DIR%

"%BIN_DIR%\mingw32-make.exe"
  • sasscがインストールできない
    gem install sasscを実行すると、以下のようなエラーメッセージが出現する。

    process_begin: CreateProcess(NULL, cc -I. -I/include/java -IC:/workspace/dev/jruby/portable-jruby-20200504-001/lib/ruby/include/ruby/backward -IC:/workspace/dev/jruby/portable-jruby-20200504-001/lib/ruby/include -I. -I./libsass/include -fPIC -fno-omit-frame-pointer -fno-strict-aliasing -fexceptions -DLIBSASS_VERSION=\"3.6.3\" -m64 -march=native -mtune=native -o c99func.o -c ./libsass/src/c99func.c, ...) failed.
    make (e=2): 指定されたファイルが見つかりません。
    mingw32-make: *** [Makefile:204: c99func.o] Error 2
    C:/workspace/dev/jruby/portable-jruby-20200504-001/lib/ruby/stdlib/rubygems/ext/builder.rb:76: warning: unsupported popen option: err
    process_begin: CreateProcess(NULL, cc -I. -I/include/java -IC:/workspace/dev/jruby/portable-jruby-20200504-001/lib/ruby/include/ruby/backward -IC:/workspace/dev/jruby/portable-jruby-20200504-001/lib/ruby/include -I. -I./libsass/include -fPIC -fno-omit-frame-pointer -fno-strict-aliasing -fexceptions -DLIBSASS_VERSION=\"3.6.3\" -m64 -march=native -mtune=native -o c99func.o -c ./libsass/src/c99func.c, ...) failed.
    make (e=2): 指定されたファイルが見つかりません。
    mingw32-make: *** [Makefile:204: c99func.o] Error 2
    ERROR:  Error installing sassc:
            ERROR: Failed to build gem native extension.

上記のエラーはccコマンドが存在しないために発生する。コンソールで以下のコマンドを実行してgccを呼び出すようにする。

set cc=gcc

恒久対策として、以下のバッチを作成してMinGWのbinディレクトリにおく。
[cc.bat]

@echo off

set BATCH_DIR=%~dp0
set BIN_DIR=%BATCH_DIR%

"%BIN_DIR%\cc.exe"
  • webpackerがインストールできない
    Node.jsがインストールされていないため、webpackerのインストールに失敗する。
    Node.jsの12.16.3をインストールする。
    また、以下のコマンドでyarnをインストールする。

    npm install -g yarn

    最後にRailsアプリのディレクトリに移動してから、以下のコマンドでwebpackerをインストールする。

    rails webpacker:install

動作確認

rails sコマンドでWebサーバーが立ち上がることを確認する。
Railsアプリのディレクトリに移動して、以下のコマンドを実行する。

rails s

以下のURLにアクセスしてRailsのサイトが表示されることを確認する。

http://localhost:3000

 

 

CosmosVFSを使ってFreeBSDからGoogleDriveをマウントした

CosmosVFSを使ってFreeBSDからGoogleDriveをマウントした

CosmosVFSは筆者が開発しているオンラインストレージサービスの抽象化レイヤである。
CosmosVFSを用いることでGoogleDriveやOneDriveといったオンラインストレージサービスをFTPや9P2000で操作することが出来る。
本稿では、FreeBSDからCosmosVFSのFTPエンドポイントを経由して、GoogleDriveをマウントした結果について解説する。
本稿が想定するFreeBSDのバージョンは12.0である。

CosmosVFSの設定

CosmosVFSのサイトやマニュアルを参考にGoogleDriveのマウントとFTPエンドポイントの作成を行う。
なお、今回は/mnt/google-driveにGoogleDriveをマウントした前提で解説を進める。

 

curlftpfs(fusefs-curlftpfs)のインストール

 

# pkg install fusefs-curlftpfs

fuseの有効化

/etc/rc.confを編集して以下の行を追加する。

fusefs_enable="YES"

/boot/loader.confを編集して以下の行を追加する。

fuse_load="YES"

CosmosVFSのFTPエンドポイントをマウント

# mkdir /mnt/ftp
# curlftpfs www.cosmos-vfs.com:10021 /mnt/ftp -o user=USERNAME:PASSWORD,custom_list="LIST"

※ custom_list=”LIST”オプションは、curlftpfsがデフォルトではFTP標準ではない”LIST -a”コマンドを送出するため、-aを抑制するために指定する。

[疎通確認]
google-driveディレクトリが表示されている。

# ls /mnt/ftp/mnt
9p2000          asteroid        google-drive
amazon-s3       ftp             one-drive

 

GoogleDriveを操作する

FTP経由でFreeBSDのファイルシステムとしてGoogleDriveをマウントできているため、以下のような操作が可能である。

[ファイル一覧の取得]
GoogleDriveのディレクトリに移動して、lsコマンドを実行する。

# cd /mnt/ftp/mnt/google-drive
# ls
hoge.txt
share
test-dir
workspace
www

 

[ファイルの作成] 
※2020/05/04現在失敗する。FTPのCREATEコマンドをCosmos側が未実装のため。

# touch hoge2.txt
touch: hoge2.txt: Operation not supported

curlftpfsのログ

LOOKUP /mnt/google-drive/hoge2.txt
getattr /mnt/google-drive/hoge2.txt
ftpfs: operation ftpfs_getattr failed because No such file or directory
   unique: 87, error: -2 (No such file or directory), outsize: 16
unique: 88, opcode: LOOKUP (1), nodeid: 3, insize: 50, pid: 2070
LOOKUP /mnt/google-drive/hoge2.txt
getattr /mnt/google-drive/hoge2.txt
   unique: 88, error: -2 (No such file or directory), outsize: 16
unique: 89, opcode: CREATE (35), nodeid: 3, insize: 66, pid: 2070
create flags: 0x202 /mnt/google-drive/hoge2.txt 0100644 umask=0022
ftpfs: operation ftpfs_open failed because Operation not supported
   unique: 89, error: -45 (Operation not supported), outsize: 16

 

[ファイルの読み書き]
既にGoogleDrive上に存在するファイルに対しては書き込みと読み込みが出来る。

# echo "hello world" > hoge.txt
# cat hoge.txt
hello world

 

[ファイルの削除]
ファイルの削除は問題なく動作する

# rm hoge.txt

 

ディレクトリの削除も問題なく動作する

# ls -la
(省略)
drwxrwxr-x  1 root  wheel         0 May  4 00:00 hoge
# rm -fr hoge

まとめ

CosmosVFSとcurlftpfsを組み合わせることで、新規ファイルの作成に難があるもののFreeBSDからGoogleDriveを操作できることを確認した。
Linuxではgoogle-drive-ocamlfuseを用いることで同様の操作ができるが、FreeBSDではそのようなアプリケーションが存在しないため、CosmosVFSを経由してGoogleDriveを操作することには有用性があるだろう。
また、動作確認はしていないが、CosmosVFSはOneDriveやAmazonS3といったストレージにも対応しているため、これらのオンラインストレージをFreeBSDにマウントして操作できると思われる。
今後の展開として、CosmosVFSにFTPのCREATEコマンドを実装することで、ファイルの新規作成に対応することを検討している。

 

その他

※作業中に以下のエラーが出たらpkg-confをインストールする

checking for GLIB... configure: error: The pkg-config script could not be found or is too old.  Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.

[pkg-configのインストール方法]

# pkg install pkgconf

 

 

 

VisualStutdio2017で作成したASP.NET CoreWebアプリをCentOS7で動かしてみた。

VisualStutdio2017で作成したASP.NET CoreWebアプリをCentOS7で動かしてみた。
基本的な流れは以下のサイトと同じ。

CentOS 7.2上に.NET Core 1.1をインストールして、Visual StudioでビルドしたASP.NET Core Webアプリをデプロイしてサービス化する – Qiita
http://qiita.com/yamaokunousausa/items/f9f2b157e0fdca045a14

上記のサイトの手順で実行しようとしたところ以下の差異があった。

・Visual Studio 2017が出力するターゲットフレームワークはデフォルトで.NETCoreApp1.1
=> jsonファイルの編集を行う必要はない

・Visual Studio 2017が出力するターゲットフレームワークはデフォルトでは1.1.2である。
=> 末尾のマイナーバージョンが0ではなく2のために実行時にエラーになる。
後述する手順で回避する。

[.Net Core 1.1.2が必要と言われる]
下記のサイトから、dotnet-centos-x64.1.1.2.tar.gzをダウンロードする.
https://www.microsoft.com/net/download/linux

※Curlなどで直接DLする際は以下のURLを使用する。
https://download.microsoft.com/download/D/7/A/D7A9E4E9-5D25-4F0C-B071-210CB8267943/dotnet-centos-x64.1.1.2.tar.gz

下記のコマンドを打つ。
sudo mkdir /opt/dotnet-1.1.2
sudo tar zxf dotnet-centos-x64.1.1.2.tar.gz -C /opt/dotnet-1.1.2
ln -s /opt/dotnet-1.1.2/dotnet /usr/local/bin

※ lnする前に先ほどの記事で作成した/usr/local/bin/dotnetをunlinkしておくこと.
unlink /usr/local/bin/dotnet

実際に動作するvagrantのVMイメージを公開できないものか検討中。

Scalaで既存のListの末尾に値を追加する

Scalaで既存のListの末尾に値を追加するのにハマった。
一応解決したけど、それが正しいやりかたかもわからん。

リストを宣言して、
scala> var list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

::で末尾に追加しようとして怒られる。
scala> list = list :: 4
<console>:8: error: value :: is not a member of Int
list = list :: 4

::でリストの先頭に追加するのは問題なく通る。
scala> list = 4 :: list
list: List[Int] = List(4, 1, 2, 3)

新しいリストを作って:::でつなげると、一応リストの末尾に追加できた。
scala> list = list ::: List(5)
list: List[Int] = List(4, 1, 2, 3, 5)

うーん、めんどい。
そういえば、昔Lispで同じような経験をしたような…
まぁ動くし、これでいっか。

Spring Bootでwarファイルを生成してTomcatで動かす雛形

Spring Bootでwarファイルを生成して、Tomcatで実行するための雛形ファイルを公開します.

http://www.loxsols.com/files/src/misc/loxsolsboot_004_war.zip
動作条件
・JDK 1.7
・Tomcat 8.5.16
・Spring Boot 1.5.4

※ tomcat 6では動かないので要注意です。

warファイルをデプロイして下記のURLを開くとjspファイルの内容が返却されるはずです。
http://localhost:8080/loxsolsboot/hello-jsp

手っ取り早く、JSPが使えるSpring Bootのwarファイルを生成したい人は活用ください。

 

 

 

 

 

Loxsols Twitter Analyzerをリリースしました。

Loxsols Twitter Analyzerは筆者のTwitterのタイムラインを形態素解析するツールです。

Loxsols Twitter Analyzer
http://www.loxsols.com/pukiwiki/index.php?Loxsols%20Twitter%20Analyzer

単語を抽出して出現頻度でソートした結果を取り出せます。
(それが何の役に立つかは(ry… )

Twitter 4JとYahoo形態素解析のAPIを使っています。

 

SpringBootServletInitializerのパッケージ構成が変更されている件

Spring Bootでjarファイルではなく、warファイルを生成してアプリケーション・サーバーにデプロイする時にSpringBootServletInitializerクラスを継承することになる。

このSpringBootServletInitializerクラスのパッケージ構成が曲者で、バージョンによっては正しくないimport文を参照することになる。

筆者の環境は以下のimport文の違いがあった。

正 : org.springframework.boot.web.support.SpringBootServletInitializer
誤 : org.springframework.boot.context.web.SpringBootServletInitializer

これのせいで、30分ほどコンパイルエラーの画面と格闘した。
例のごとく、Stack overflowが参考になった。
Spring Boot: SpringBootServletInitializer is deprecated
https://stackoverflow.com/questions/38843015/spring-boot-springbootservletinitializer-is-deprecated

springも一度リリースしたパッケージ構成をさらっと変えないでほしいな。

 

Loxols OCR翻訳 LINE BOT をリリースしました.

Loxols OCR翻訳 LINE BOTをリリースしました.
http://www.loxsols.com/pukiwiki/index.php?Loxols%20OCR%E7%BF%BB%E8%A8%B3%20LINE%20BOT

ls-ocr-tl-000
Loxols OCR翻訳 LINE BOTは、画像データの翻訳に対応したLINEの翻訳BOTです。
日本語と多言語の翻訳に対応しています。
入力した文字列が日本語の場合は、英語へ翻訳します。
日本語以外の文字列を入力した場合は、日本語へ翻訳します。

ls-ocr-tl-005

画像データを受け付けた場合は、BOT内部でOCR処理を行い、テキストデータを抽出して翻訳します。
ls-ocr-tl-003
※本サービスの運営には費用がかかるため、一定期間公開して利用者が少ないようであれば公開を停止します。予めご了承ください。

 

 

 

 

 

 

Spring Bootでapplication.propertiesに定義した独自の値を読み取る方法

Spring Bootで、application.propertiesには色々な魔法のキーワードを打ち込むけど、独自にキーと値を設定することも出来る。

んで、このapplication.propertiesに設定した値が読めなくて2時間ほどハマった。
日本語の資料を探そうとして見つからず、リソースリーダーとか触りだしてハマった。

こういうときは素直に英語でググりましょう。
Spring Boot application.properties read っと。
初っ端からヒットしました。

How to access a value defined in the application.properties file in Spring Boot
https://stackoverflow.com/questions/30528255/how-to-access-a-value-defined-in-the-application-properties-file-in-spring-boot

application.propertiesで下記のよう記載した場合、

userBucket.path=${HOME}/bucket

クラスでは下記のようにコーディングする。

@Value("${userBucket.path}")
private String userBucketPath;

 

さすが、StackOverFlowでした。