Mavenで実行するテストをIDEAでデバッグする #Maven #IntelliJ

概要

IntteliJ IDEAで、Mavenプロジェクトのtestフェーズをデバッグ実行した場合に、ブレークポイントで止まってくれない(ステップ実行ができない)現象に遭遇した。

Mavenはデフォルトだとテストが別の(forkした)プロセスで実行されるため、IDEAがテストの実行プロセスを捕まえられないようだ。

実行時に -DforkCount=0 オプションをつけるとデバッグできるようになる。

$ mvn -DforkCount=0 test

補足

Maven Surefire Pluginmaven.surefire.debug プロパティを使えば、リモートデバッグの要領でforkしたプロセスでもデバッグはできるよう。

ただテストをデバッグしたいのって、IDEで開発中のことがほとんどだろうし、いっそforkさせないようにした方が楽と思われる。

forkMode=never というパラメータもあるが、これは互換性のために残された古いものなので、forkCountを利用したほうがよい。

参考

AWS CodeDeployを使う時のEC2のセットアップ #AWS

概要

CodeDeployを使ってEC2にデプロイするときに準備すること。

既にEC2インスタンス自体は存在することを想定。

AWS CodeDeployエージェントのインストール

docs.aws.amazon.com

  • rubywgetを先に入れておく必要があるようだ
# ステータス
sudo service codedeploy-agent status
# 起動
sudo service codedeploy-agent start
# 停止
sudo service codedeploy-agent stop
# 再起動
sudo service codedeploy-agent restart
  • エージェントのログ
    • /var/log/aws/codedeploy-agent/codedeploy-agent.log
  • デプロイするartifact
    • /opt/codedeploy-agent/deployment-root/{デプロイグループID}/{デプロイID}/deployment-archive/
  • hookで実行したスクリプトのログ
    • /opt/codedeploy-agent/deployment-root/{デプロイグループID}/{デプロイID}/logs/scripts.log

IAMインスタンスプロファイルの作成

docs.aws.amazon.com

IAMロールをインスタンスにアタッチする

docs.aws.amazon.com

associate-iam-instance-profile — AWS CLI 1.15.17 Command Reference

# こんな感じ
aws ec2 associate-iam-instance-profile \
  --instance-id {EC2のインスタンスID} \
  --iam-instance-profile Arn={IAMロールのARN}
  • ArnじゃなくてNameのオプションもある
  • アタッチした後、Codeデプロイエージェントは再起動しないとダメっぽい

参考

qiita.com

AWS CodeDeployのApplicationStopは旧リビジョンのスクリプトが使われる #AWS

概要

CodeDeployのApplicationStopは旧リビジョンのスクリプトが使われる。

どういう問題が起きるか?

一度デプロイに成功した後、二度目以降で発生するようなバグがApplicationStopのスクリプトで発生すると、再試行してもエラーになり続ける。

(新しい修正したスクリプトを使ってくれないので)

あんまり発生しなそうだけど、自分が踏んだのは下記のようなケース。

  • アプリケーションが停止できなかった場合はエラーにするような停止スクリプト
  • EC2インスタンスを別件(スケールアップ)のために再起動した
  • 再起動のタイミングでCodeDeployに関係なくアプリケーションは停止
  • CodeDeployを動かすと、アプリが停止できない(そもそも起動してない)のでスクリプトがエラー
  • 停止スクリプトを修正するも、反映されない(古いスクリプトが使われるから)

どう対応したか

もう全てを最初からやり直すことにした。

  1. /opt/codedeploy-agent/deployment-root/[デプロイグループID]/ 配下にartifactのキャッシュがデプロイID単位で配置されているので、丸っと消す。
  2. /opt/codedeploy-agent/deployment-root/deployment-instructions/ 配下に前回デプロイ情報が残されてるので、丸っと消す。
  3. 前回デプロイしたモジュールを削除する

これで再デプロイする。

前回デプロイしたモジュールを削除するのは、CodeDeployは自身がデプロイしたモジュールが既に配置されていた場合、エラーになるため。 (つまり、上書きデプロイに制限がある)

キャッシュ等を削除することにより、今あるモジュールがCodeDeployによって配備されたものだと認識できなくなってしまうので削除する必要がある。

参考

qiita.com qiita.com

AWS CodeDeployでSpringBootのデプロイが終わらない #AWS

概要

AWS CodeDeployを使ってSpringBootをEC2にデプロイするようにした。

bashスクリプトを使って、javaコマンドのバックグラウンド実行(&)で起動したところデプロイが終わらなかった。

もう少し正確にいうと、スクリプトは期待通りに動作し、Bootアプリケーションも起動したのだが、CodeDeployがアプリが起動済なことを認識してくれなかった。

原因と対策

どうも単にjavaコマンドでバックグラウンド実行すると、標準入出力を掴んでしまい、そうするとCodeDeployがスクリプトの終了を検知してくれない模様。

標準入出力を適当にリダイレクトするようにしたら解決した。

プロダクション環境なんかではログ設計・出力が精査された状態なら、 /dev/null に捨ててもいいかもしれない。

詳細

appspec.ymlはこんな感じ

version: 0.0
os: linux
files:
  - source: sample-app.jar
    destination: /home/ubuntu
permissions:
  - object: /home/ubuntu
    pattern: "*.jar"
    owner: ubuntu
hooks:
  ApplicationStop:
    - location: stop.bash
      timeout: 300
      runas: ubuntu
  ApplicationStart:
    - location: start.bash
      timeout: 300
      runas: ubuntu

起動スクリプトはこんな感じ

#!/usr/bin/env bash

set -eu

readonly APPLICATION_ROOT_DIR="/home/ubuntu"

# 単純なバックグラウンド実行だとCodeDeploy側で終了を検知してくれない
# java -jar "${APPLICATION_ROOT_DIR}/sample-app.jar &"

# 標準入出力をログにリダイレクトするようにした
java -jar "${APPLICATION_ROOT_DIR}/sample-app.jar" \
    >> "${APPLICATION_ROOT_DIR}/sample-app.log" \
    2>&1 &

補足

serviceとして起動する方法もあるみたい

qiita.com

参考

ApplicationStart hook is pending after starting process in background

Web制作者のためのUXデザインをはじめる本を読んだ

Web制作者のためのUXデザインをはじめる本 ユーザビリティ評価からカスタマージャーニーマップまで

Web制作者のためのUXデザインをはじめる本 ユーザビリティ評価からカスタマージャーニーマップまで

僕はUXデザイナではないけれど、UXについてもう少し具体的な知識がほしいなぁと思って読んでみた。

非常に分かりやすくて、実践的な手法がまとまっていると思う。

特に知りたかった、ユーザビリティテストの仕方が丁寧に紹介されていたのはうれしい。

実際のテストだけではなく、事前のペルソナ準備や、テスト後の分析についても触れられている。

後半は少し抽象度が上がってしっくり来ないところもあったんだけど、UXデザインの難易度も上がっていくということかなと思った。

組織への導入についても触れられているけど、この辺の話はエンジニアリングでも何でも変わらないなぁと感じた。

「ユーザーテストしてフィードバックもらわなきゃだめなんだ!」→「でもユーザーテストってどうやるのん?」な人におすすめ。

AWS CodeBuild でMaven Wrapperが使えない #AWS初心者

概要

AWS CodeBuildで提供されているJavaビルド環境( aws/codebuild/java:openjdk-8 )ではMaven Wrapperがエラーなってしまう。

Mavenはイメージに含まれているのでそれをそのまま使うか、別イメージを利用する必要がありそう。

詳細

CIツールとしてCodeBuildを使ってみようとしていたのだが、ビルドがエラーになってしまった。

[ERROR] Unknown lifecycle phase "/root/.m2". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>.

ビルゴ環境はAWSが提供している aws/codebuild/java:openjdk-8 を使用しており、buildspec.ymlは下記の通り(抜粋)。

build:
  commands:
    - echo Build started on `date`
    - ./mvnw clean install

ログを頼りに調べてみると下記のような情報が。

https://issues.jenkins-ci.org/browse/JENKINS-47890

イメージの中身まで正確に確認したわけではないけど、Maven Wrapperの使っている環境変数MAVEN_CONFIG)に別の値が設定されているとエラーになってしまう模様。

公式のサンプルのようにMavenコマンドを使うよう( mvn clean install )にしたらビルドは成功した。

ただ折角Javaだけで動作できるようにMaven Wrapperを入れているので、別のイメージ(DockerHubのOpenJDKあたり)を使うようにしようかなと思う。

MacでNginxを使ってみる #nginx

Apacheおじさんの道は遠い。

インストール

brewで入れられる

$ brew install nginx

バージョンを確認してみる。

$ nginx -V
nginx version: nginx/1.13.12

起動

nginxで起動できる

$ nginx

curlで確認してみる。デフォルトだと8080で起動するようだ。

$ curl http://localhost:8080

IPv6に対応させる

MacOSのバージョンやhostsの設定にもよるが、localhostIPv6で解決しようとしてエラーになってしまうことがある。

curl: (52) Empty reply from server

デフォルトの設定に、IPv6でのLISTENも追加する。

設定ファイルは /usr/local/etc/nginx/nginx.conf

server {
    listen       8080;
    # IPv6を追記
    listen [::]:8080;
    server_name  localhost;

    # 略
}

その他

停止はStop

$ nginx -s stop

再起動はReload

$ nginx -s reload

設定ファイルのシンタックスチェックがtオプションで可能

$ nginx -t

コンテンツのデフォルトの配置場所は /usr/local/Cellar/nginx/1.13.12/html らへん