ソフラボの技術ブログ

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

MacのRubyを最新バージョンにする

環境

macOS:10.14.6
Ruby:2.3.7p456 (2018-03-28 revision 63024)
Homebrew:2.4.9

手順

Homebrewがインストールされているのを前提で説明します。


1.Homebrewでrbenvをインストールする

$ brew install rbenv


2.インストール可能なRubyのバージョンを確認する

$ rbenv install --list
2.5.8
2.6.6
2.7.1
jruby-9.2.12.0
maglev-1.0.0
mruby-2.1.1
rbx-5.0
truffleruby-20.1.0
truffleruby+graalvm-20.1.0


3.リストにある最新のバージョンでRubyをインストールする

$ rbenv install 2.7.1

インストールに意外と時間がかかります


4.デフォルトのRubyバージョンを設定します。

$ rbenv global 2.7.1


5.~/.bash_profileに設定を追加する

$ vi ~/.bash_profile
# 以下を追記する
eval "$(rbenv init -)" 


6.設定を有効化する

$ source ~/.bash_profile


7.バージョンが切り替わっているか確認する

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin18]


たのしいRuby 第6版 (Informatics&IDEA)

たのしいRuby 第6版 (Informatics&IDEA)

WildFlyでSpringBoot2.xを起動するとエラーになる場合の対処方法

WildFlyでSpringBoot2.xを動かそうとすると、以下のエラーが発生しアプリが起動しません。

(ServerService Thread Pool -- 78) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDetailsServiceImpl': Unsatisfied dependency expressed through field 'loginService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginService': Unsatisfied dependency expressed through field 'usersDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usersDaoImpl' defined in VFS resource ["/Users/xxx/dev/eclipse/server/wildfly-20/standalone/deployments/WebApp.war/WEB-INF/classes/com/example/dao/UsersDaoImpl.class"]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; nested exception is org.springframework.aop.framework.AopConfigException: Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well; nested exception is java.lang.NoSuchMethodException: com.example.dao.UsersDaoImpl$$EnhancerBySpringCGLIB$$31fd9af9.<init>()

どうもDIできてないのが原因ぽいです。
Java9以降で発生します。
対処方法は、設定ファイルに追記するだけなので簡単です。

環境

OS:CentOS7
WildFly:20
SpringBoot:2.3.1
Java:14

対処方法

jboss-deployment-structure.xmlに依存関係の設定を追加する。

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <deployment>
        <dependencies>
        	<module name="jdk.unsupported"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

EclipseでWildFlyのjboss-deployment-structure.xmlをローカルサーバーに配置する方法

EclipseのローカルWildFly動作時に、jboss-deployment-structure.xmlをWEB-INFに配置する方法です。
プロジェクトのプロパティ内で行えます。

手順

1.「src」配下に任意のフォルダを作成する
ここでは「WEB-INF」フォルダを作成する。
f:id:shinsuke789:20200720093009p:plain

2.プロジェクトのプロパティで「デプロイメント・アセンブリ」を選択し、右側にある「追加」ボタンを押下する
f:id:shinsuke789:20200720093016p:plain

3.ディレクティブ・タイプ選択で「フォルダ」選択し、「次へ」を押下する
f:id:shinsuke789:20200720093028p:plain

4.1で作成したフォルダを選択し、「完了」を押下する
f:id:shinsuke789:20200720093037p:plain

5.追加したソースのデプロイ・パスをクリックし、サーバー上でのパスである「WEB-INF」を入力し、設定を保存する
f:id:shinsuke789:20200720093046p:plain

Linuxでシェルを使ってDropboxにバックアップをする方法

サーバーを運用していると障害発生時にデータが消えても大丈夫なようにバックアップを取る必要があります。

物理的なサーバーに触れられるのであれば、外付けHDDやテープ装置等にバックアップを取ったりいろいろ手段はあります。

しかし、VPS等のクラウド上のサーバーとなると外付けHDD等を接続することができません。

サーバー外にバックアップを気楽に取れるDropboxを使った方法を紹介します。

手順

Dropbox developerにアプリを登録する

1.Dropbox developerサイトにアクセスする
www.dropbox.com

2.「Create App」を押下する
f:id:shinsuke789:20200723103847p:plain

3.「1. Choose an API」で「Dropbox API」を選択する
f:id:shinsuke789:20200723103856p:plain

4.「2. Choose your app's permissions model」で「Scoped access」を選択する
f:id:shinsuke789:20200723103907p:plain

5.「3. Choose the type of access you need」で「App folder」を選択する
f:id:shinsuke789:20200723103926p:plain

6.「4. Name your app」で任意の名前を入力する
f:id:shinsuke789:20200723103938p:plain

7.画面右下の「Create App」を押下する
f:id:shinsuke789:20200723103946p:plain

8.パーミッションを設定する
よくわからないので、画像のように設定して下さい。
f:id:shinsuke789:20200723104006p:plain
f:id:shinsuke789:20200723104012p:plain
f:id:shinsuke789:20200723104020p:plain
f:id:shinsuke789:20200723104058p:plain

9.後ほど使うアクセストークンを取得する
f:id:shinsuke789:20200723104105p:plain
アクセストークンを生成すると、Dropboxのルート配下に「アプリ」フォルダ、その配下に先程つけた名前のフォルダが自動的に作成されます。

Linuxdropbox_uploader.shを設定する

1.dropbox_uploader.shを任意のディレクトリにダウンロードする

$ wget https://raw.githubusercontent.com/andreafabrizi/Dropbox-Uploader/master/dropbox_uploader.sh

wgetがない場合、yum等でインストールして下さい。


2.dropbox_uploader.shを実行する

$ ./dropbox_uploader.sh

3.Access tokenを聞かれるので、Dropbox developerで取得したアクセストークンを貼り付け、Enter押下後、「y」を入力しEnterを押下する

 This is the first time you run this script, please follow the instructions:

 1) Open the following URL in your Browser, and log in using your account: https://www.dropbox.com/developers/apps
 2) Click on "Create App", then select "Dropbox API app"
 3) Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder
 4) Enter the "App Name" that you prefer (e.g. MyUploader37321544428431)

 Now, click on the "Create App" button.

 When your new App is successfully created, please click on the Generate button
 under the 'Generated access token' section, then copy and paste the new access token here:

 # Access token:ここにアクセストークンを貼り付ける

 > The access token is xxxxxxxxxxx. Looks ok? [y/N]: yと入力する

4.dropboxとの連携が設定される

アクセストークンを変更したい場合、dropbox_uploader.shを実行したユーザーのホームディレクトリ配下にある「.dropbox_uploader.sh」を編集し、該当のアクセストークンを削除するか、ファイルごと削除します。
sudoで実行した場合、rootのホームディレクトリ配下のファイルを編集します。

dropbox_uploader.shを使ってアップロードする

アップロードのコマンドは以下の通りです。

$ ./dropbox_uploader.sh upload アップロードするファイル名 アップロード後のdropbox内でのファイル名

例:
$ ./dropbox_uploader.sh upload /home/user/hoge.tar.gz hoge.tar.gz

シェルを実行すると「dropboxルート/アプリ/アプリ名」に自動的にアップロードされます。
同じ名前でアップロードするようにしていると、Dropbpx無料版では最大30日間のバージョン管理がされます。
また、ファイル内容が前回と異なる場合のみバージョン管理されます。

実際の運用は、別のシェル内でdropbox_uploader.shを呼び出し、cronでシェルが実行されるようにする感じになります。

無料でDropboxの容量を増やす方法

以下のリンク経由でDropboxをインストールすると無料で500MBが永久的に付与されます。
Dropbox - You're invited to join Dropbox!

まとめ

基本的にdropbox_uploader.sh1つに付き1アプリが紐づくようになっています。
コマンド実行時にアップロード先を指定する必要はなく、すべてDropbox developerでのアプリ作成で設定されます。
サーバーでの外部バックアップを気楽に行うには、紹介したこの方法が一番手軽な方法かもしれません。

MacでPostfixを使ってGmail経由でメールを送信する

メールを送信するサービス等を開発していると、メール送信テストをする必要が出てきます。
開発環境でPostfixを使ってGmail経由でメール送信する方法を紹介します。

環境

macOS:10.14.6
Postfix:3.3.2(デフォルトのまま)

補足

Postfixのバージョン確認

$ postconf | grep mail_version
mail_version = 3.2.2
milter_macro_v = $mail_name $mail_version

手順

1.main.cfでメールの設定を行う

$ sudo vi /etc/postfix/main.cf
relayhost = [smtp.gmail.com]:587
mail_spool_directory = /var/spool/mail
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
smtp_tls_security_level = may

Postfix2.3以降は「smtp_use_tls = yes」ではなく「smtp_tls_security_level = may」を使います。

http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html#smtp_use_tls

smtp_use_tls (デフォルト: no)
この機能はPostfix 2.2以降で使えます。Postfix 2.3以降では smtp_tls_security_level を代わりに使ってください。


2.Googleでアプリパスワードを取得する
以下のサイトを参考にアプリパスワードを取得します。
バイスは「mac」を選択します。
www.howtonote.jp


3.送信時の認証情報を設定する

# 認証情報の作成
$ sudo vi /etc/postfix/sasl_passwd
[smtp.gmail.com]:587 hoge@gmail.com:取得したパスワード

# 権限変更
$ sudo chmod 600 /etc/postfix/sasl_passwd

# ハッシュ化
$ sudo postmap /etc/postfix/sasl_passwd


4.スプールを設定する

# ディレクトリ作成
$ sudo mkdir /var/spool/mail

# 所有者・グループの変更
$ sudo chown ログインユーザー名:staff /var/spool/mail

# 権限の変更
$ sudo chmod 700 /var/spool/mail


5.Postfixをリロードする

# すでに起動している場合
$ sudo postfix reload

# 停止
$ sudo postfix start

# 起動
$ sudo postfix stop

5.メール送信テストを行う
送信前に後で説明するメール送信ログの出力を行います。

$ mail hoge@gmail.com(送信先アドレス)
Subject: test # タイトル
test # 本文
. # メールを送信する

6.メールが届いているか確認する

メール送信ログ

Macではmaillogが生成されないようなので、メール送信前に以下のコマンドを実行しておきます。

$ log stream --predicate  '(process == "smtpd") || (process == "smtp")' --info

次のようなメッセージが表示された場合、メール送信に失敗しています。

(host smtp.gmail.com[74.125.203.108] said: 530-5.7.0 Authentication Required. Learn more at 530 5.7.0  https://support.google.com/mail/?p=WantAuthError o8sm917374pjf.37 - gsmtp (in reply to MAIL FROM command))


送信が成功した場合、次のようなメッセージが表示されればOKです。

to=<hoge@gmail.com>, relay=smtp.gmail.com[2404:6800:4008:c01::6d]:587, delay=2.6, delays=0.02/0.04/1.5/1, dsn=2.0.0, status=sent (250 2.0.0 OK  1595305690 z25sm18507895pfg.140 - gsmtp)

MecurialをGitに変換する

愛用しているバージョン管理サービスのbitbucketでMercurialの提供を終了し、Gitに完全移行するということで、既存のMercurialリポジトリをGitに移行してみました。

記事を公開するまでの期間が長かったため、抜けや間違い等があるかもしれないので、参考程度にしてみてください。

動作環境

Mac
Homebrew

環境構築

MecurialをGitに変換するための環境を構築します。

Pythonの確認

$ python --version
Python 2.7.10

# インストールされてなければ
$ brew install python2

pipの確認(Pythonのパッケージ管理)

# インストール確認
$ pip
-bash: pip: command not found

# curlでpipを取得
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1764k  100 1764k    0     0  3484k      0 --:--:-- --:--:-- --:--:-- 3488k

# pipをインストール
$ python get-pip.py --user
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Collecting pip
  Using cached pip-20.0.2-py2.py3-none-any.whl (1.4 MB)
Collecting wheel
  Using cached wheel-0.33.6-py2.py3-none-any.whl (21 kB)
Installing collected packages: pip, wheel
  WARNING: The scripts pip, pip2 and pip2.7 are installed in '/Users/xxxxx/Library/Python/2.7/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script wheel is installed in '/Users/xxxxx/Library/Python/2.7/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-20.0.2 wheel-0.33.6

# 環境変数を設定
$ vi ~/.bash_profile
export PATH=$PATH:$HOME/Library/Python/2.7/bin

# 環境変数の有効化
$ source ~/.bash_profile

PythonにMecurialをインストール

$ pip install mercurial
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Defaulting to user installation because normal site-packages is not writeable
Collecting mercurial
  Downloading mercurial-5.2.2.tar.gz (7.3 MB)
     |████████████████████████████████| 7.3 MB 2.3 MB/s 
Building wheels for collected packages: mercurial
  Building wheel for mercurial (setup.py) ... done
  Created wheel for mercurial: filename=mercurial-5.2.2-cp27-cp27m-macosx_10_14_intel.whl size=2728813 sha256=f0b70639c66146acc92e93b5d1325c68d5ab60eee4f62208d43ba4ad1f47821f
  Stored in directory: /Users/xxxxx/Library/Caches/pip/wheels/64/d4/95/33110d3cbdbafbd02d90913d03b12064730908962c08990d68
Successfully built mercurial
Installing collected packages: mercurial
Successfully installed mercurial-5.2.2

作業ディレクトリの作成

任意の場所に作業用ディレクトリを作成します。

MecurialをGitに変換する

変換ツールをダウンロードする

$ git clone https://github.com/frej/fast-export.git

変換

# Mecurialリポジトリに移動
$ cd HgRepo

# コミットログの登録ユーザー名を一覧に出力
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors

# ユーザー名を変換でできる形式に変更
$ vi ../authors
# Mecurialでのユーザー一覧
User1
Yamada Taro
# 上記を以下の形式に書き換えて保存
"User1"="User1 <user1@gmail.com>"
"Yamada Taro"="Yamada Taro <yamada_taro@yahoo.co.jp>"

# Mecurialリポジトリ内でGitリポジトリを作成
$ git init

# 変換時にエラーが出るので設定を変更しておく
$ git config core.ignoreCase false

# 変換を実行する
$ ../fast-export/hg-fast-export.sh -r . -A ../authors

変換したソースをリモートにプッシュする

# リモート設定
$ git remote add origin https://xxxxx@bitbucket.org/xxxxx/GitRepo.git

# プッシュ
$ git push origin master

# タグを一括でプッシュ
$ git push origin master --tags

docker上のPHPでEXIFを使えるようにする

PHPで画像からEXIF情報を取得するには、exif_read_data関数を使います。
しかし、この関数だけでは動作しないのでEXIFモジュールを追加する必要があります。
docker上でEXIFモジュールを追加する方法をまとめました。

動作環境

Mac
・docker
・docker php:7.3-apache

手順

1.Dockerfileに以下を追記します。

RUN && apt-get install -y \
		libfreetype6-dev \
		libjpeg62-turbo-dev \
		libpng-dev \
        && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
	&& docker-php-ext-install -j$(nproc) gd  exif \

2.Dockerfileを実行しイメージを作成します。

3.PHPexif_read_dataを実行しエラーが出ないか確認します。

php.iniに設定を追加する必要はありません。Windows環境の場合、必要です。