はじめに
以前、App Service における Tomcat アプリケーションへの war ファイルのデプロイについて と題して Tomcat 構成への war デプロイについて書きましたが、今回は Java SE Stack への Jar ファイルデプロイについて書きます。
TL;DR
- jar ファイルのデプロイには、Kudu publish API
/api/publish?type=jar
を使おう(azure-webapp-maven-plugin や AZ CLIも内部的にはこのAPIを呼び出している) - Kudu publish API を使うとjar ファイルは、
%HOME%\site\wwwroot\app.jar
(Linux の場合は$HOME/site/wwwroot/app.jar
) として保存される - app.jar はアプリケーション起動時に、JavaBootstrapper によってローカルコピーされたのちに、実行されることになる
検証環境
OS: Windows
SKU: B1
Java: AutoUpdate
JavaSE: AutoUpdate
デプロイしてみる
今回は mvn を利用してみますが、curl 等でも基本的には同じです。
mvn clean package azure-webapp:deploy
ローカルのコンソールには以下のようなログが出力されることになります。
[INFO] Trying to deploy artifact to toshida-java-se...
[INFO] Deploying (/プロジェクトパス/gs-spring-boot/complete/target/spring-boot-complete-0.0.1-SNAPSHOT.jar)[jar] ...
[INFO] Successfully deployed the artifact to https://アプリ名.azurewebsites.net
この時 App Service (Kudu) 側で何が実行されたかは、Kudu のログからわかります。
成功していれば以下のように、POST_api-publish_200_3s.xml などといったログファイルが存在しています。
このファイルの中身をみると
1行目には受信リクエストの詳細が記載されています POST /api/publish?type=jar
が呼び出されていることなどがわかります。
また、2行目移行にはリクエストを受け取って Kudu が実行した処理のログが残されています。
概ね以下のような処理となっています。受信リクエストからjarファイルを D:\local\Temp\zipdeploy\extracted\app.jar
として保存、デプロイ処理として、D:\local\Temp\zipdeploy\extracted\app.jar
を home\site\wwwrootに配置、アプリケーションの再起動がトリガーされます。
実際には改行されていません。記事に不要な項目は削除しています。
<step title="Incoming Request"
date="2022-12-12T09:48:35.270"
url="/api/publish?type=jar"
method="POST"
type="request"
pid="4680,2,31"
Date="Mon, 12 Dec 2022 09:48:34 GMT"
Content-Length="19734840"
Content-Type="application/octet-stream"
Accept="*/*"
Authorization="Bas..."
Host="アプリ名.scm.azurewebsites.net"
User-Agent="azure-webapp-maven-plugin/2.5.0 installationId:f99d07082807b507a4734481c82a4a2cbfcd1f8f477050ca681bb818ca5df41c sessionId:ca87405e-5628-4021-ab02-ce50e9f02038 azsdk-java-com.azure.resourcemanager.resources.fluentcore.policy/2.10 (11.0.10; Linux; 5.10.102.1-microsoft-standard-WSL2)"
x-ms-return-client-request-id="true"
ここまでは概ね、[App Service における Tomcat アプリケーションへの war ファイルのデプロイについて]で記載した、/api/publish?type=war
の動作とほぼ同様です。保存ファイル名が app.war か app.jar で違う程度です。
以下のように wwwroot 配下には app.jar が保存されることになります。
ただし、?type=war の場合と違ってパスを指定してデプロイすることはできず、保存先は必ず app.jar
となります。
- type=jar: JAR パッケージを /home/site/wwwroot/app.jar にデプロイします。 path パラメーターは無視されます
アプリケーション起動処理
Tomcat スタックの場合と同様に、Windows 環境では w3wp.exe のプロセスの配下に、JavaBootstrapper が存在することがわかります。
Tomcat スタックとの違って、catalina.bat に該当する cmd が JavaBootstrapper と java の間にはありません。
今回は catalina.log がないので jcmd
で java プロセスの詳細を見てみます。
Tomcat の場合に、war ファイルがコピーされていたローカルパスと同じような、C:/DWASFiles/Sites/アプリ名/Temp/javaFiles<UUIDっぽい値>\site\wwwroot
配下の app.jar をクラスパスに追加していることがわかります。そのほかに azure.appservice.jar
というjar も追加されています。
スタートアップスクリプトによる検証
Tomcat スタックでの確認と同様に、startup.cmd
を使って JavaBootstrapper によって、実行直前にどのような状態になっているのかを見てみます。
set CURRENT_DATE=%date:~10,4%%date:~4,2%%date:~7,2%
set logfile=%HOME%\LogFiles\startup_%CURRENT_DATE%.log
echo "==== startup.cmd start ===" >> "%logfile%" 2>&1
date /t >> "%logfile%" 2>&1
time /t >> "%logfile%" 2>&1
echo "AZURE_JAVA_APP_PATH = %AZURE_JAVA_APP_PATH%">> "%logfile%" 2>&1
echo "AZURE_SITE_HOME = %AZURE_SITE_HOME%">> "%logfile%" 2>&1
:: 以下の2行は%AZURE_JAVA_APP_PATH%の最後が \app.jar で終わることを知った上で足しています
echo %AZURE_JAVA_APP_PATH:~,-8%
dir %AZURE_JAVA_APP_PATH:~,-8% >> "%logfile%" 2>&1
実行結果
Mon 12/12/2022
10:50 AM
"AZURE_JAVA_APP_PATH = C:\DWASFiles\Sites\<アプリ名>\Temp\javaFiles\8edff953-2dab-481e-b53e-3dee4422fe02\site\wwwroot\app.jar"
"AZURE_SITE_HOME = "
Volume in drive C is Temporary Storage
Volume Serial Number is AA7C-C278
Directory of C:\DWASFiles\Sites\<アプリ名>\Temp\javaFiles\8edff953-2dab-481e-b53e-3dee4422fe02\site\wwwroot
12/12/2022 10:50 AM <DIR> .
12/12/2022 10:50 AM <DIR> ..
12/12/2022 09:48 AM 19,734,840 app.jar
1 File(s) 19,734,840 bytes
2 Dir(s) 11,674,025,984 bytes free
Tomcat スタックの場合は、AZURE_SITE_HOME
がありましたが、今回は AZURE_JAVA_APP_PATH
として、ローカル領域の app.jar
が指定されていることがわかります。
そして、再起動を繰り返す度に javaFiles
以下の例えば 8edff953-2dab-481e-b53e-3dee4422fe02
の値が変わることがわかります。
app.jar 以外を使うには
WEBSITE_JAVA_JAR_FILE_NAME
というデフォルト値が app.jar
の設定があります。
https://learn.microsoft.com/ja-jp/azure/app-service/reference-app-settings?tabs=kudu%2Cjava
ソースを更新してパッケージしたjarファイルをFTPで %HOME%\site\wwwroot\version2.jar
として配置し、WEBSITE_JAVA_JAR_FILE_NAME
に version2.jar
を設定してみます。
startup.cmd で確認すると
AZURE_JAVA_APP_PATH
が C:\DWASFiles\Sites\<アプリ名>\Temp\javaFiles\fa1dbffc-425f-4389-8b18-f765b5b3c57f\site\wwwroot\version2.jar
のような値になっていることがわかります。
Tomcat スタックの場合は、war ファイルを展開して Tomcat が読み込むことでコンテキストパスという概念が存在しそれがアプリケーションアクセス時の URL にも影響してきますが、Java SE スタックの場合は結局のところなんらかの jar ファイルをローカル領域にコピーして実行しているだけとなります。
アプリケーションが jar ファイルの名前を利用してなにか処理しているなど、 app.jar
というファイル名を使いたくないというユースケースはあまり思い浮かびませんが、AZURE_JAVA_APP_PATH
を利用することで app.jar
以外を利用することも可能です。
ただしその場合は、az cli, maven plugin をはじめ、/api/publish?type=jar に準拠するデプロイ方法は以外でファイルを配置する必要があります。
参考リンク