演習 - JBoss EAP on Azure App Service に Jakarta EE アプリケーションをデプロイする
このユニットでは、Azure App Service 上の Red Hat JBoss Enterprise Application Platform (JBoss EAP) に Jakarta EE アプリケーションをデプロイします。 Azure App Service 用の Maven プラグインを使用して、プロジェクトの構成、アプリケーションのコンパイルとデプロイ、データ ソースの構成を行います。
アプリを設定する
次の手順を使用して、Azure App Service 用の Maven プラグインを使用してアプリを構成します。
次のコマンドを使用して、Azure プラグインの構成目標を対話形式で実行します。
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
Von Bedeutung
MySQL サーバーのリージョンを変更する場合は、待機時間の遅延を最小限に抑えるために、そのリージョンを Jakarta EE アプリケーション サーバーのリージョンと一致させる必要があります。
対話型プロンプトに応答するには、次の表の値を使用します。
Input 要素 価値 Create new run configuration (Y/N) [Y]:
Y
Define value for OS [Linux]:
Linux
Define value for javaVersion [Java 17]:
1: Java 17
Define value for runtimeStack:
3: Jbosseap 7
Define value for pricingTier [P1v3]:
P1v3
Confirm (Y/N) [Y]:
Y
次の出力が一般的です。
[INFO] Saving configuration to pom. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 03:00 min [INFO] Finished at: 2025-02-21T06:24:11+09:00 [INFO] ------------------------------------------------------------------------
Maven コマンドを使用した後、Maven pom.xml ファイルに一般的な追加例を次に示します。
<build> <finalName>ROOT</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> <plugin> <groupId>com.microsoft.azure</groupId> <artifactId>azure-webapp-maven-plugin</artifactId> <version>2.13.0</version> <configuration> <schemaVersion>v2</schemaVersion> <resourceGroup>jakartaee-app-on-jboss-rg</resourceGroup> <appName>jakartaee-app-on-jboss</appName> <pricingTier>P1v3</pricingTier> <region>centralus</region> <runtime> <os>Linux</os> <javaVersion>Java 17</javaVersion> <webContainer>Jbosseap 7</webContainer> </runtime> <deployment> <resources> <resource> <directory>${project.basedir}/target</directory> <includes> <include>*.war</include> </includes> </resource> </resources> </deployment> </configuration> </plugin> </plugins> </build>
pom.xmlファイル内の
<region>
要素を確認します。 その値が MySQL のインストール場所と一致しない場合は、同じ場所に変更します。次の例を使用して、Azure App Service 上の JBoss EAP 8 環境に対して、pom.xml ファイル内の
webContainer
値をJbosseap 8
するように変更します。ヒント
2025 年 2 月の時点で、JBoss EAP の最新バージョンは 8.0 Update 4.1 です。
<runtime> <os>Linux</os> <javaVersion>Java 17</javaVersion> <webContainer>Jbosseap 8</webContainer> <!-- Change this value --> </runtime>
pom.xml ファイルの
<resources>
要素に次の XML を追加します。 この構成は、このユニットの後半で更新するスタートアップ ファイルを展開するために使用されます。<resource> <type>startup</type> <directory>${project.basedir}/src/main/webapp/WEB-INF/</directory> <includes> <include>createMySQLDataSource.sh</include> </includes> </resource>
startup
のリソース<type>
値は、指定されたスクリプトを Linux または Windows 用のstartup.cmdの startup.sh ファイルとしてデプロイします。 展開場所は /home/site/scripts/ です。注
展開オプションと展開場所を選択するには、次のいずれかの方法で
type
を指定します。-
type=war
path
が指定されていない場合は、WAR ファイルを /home/site/wwwroot/app.war にデプロイします。 -
type=war&path=webapps/<appname>
は、WAR ファイルを /home/site/wwwroot/webapps/<appname> に展開します。 -
type=jar
は、WAR ファイルを /home/site/wwwroot/app.jar に展開します。path
パラメーターは無視されます。 -
type=ear
は、WAR ファイルを /home/site/wwwroot/app.ear にデプロイします。path
パラメーターは無視されます。 -
type=lib
は、JAR を /home/site/libs にデプロイします。 パラメーターpath
指定する必要があります。 -
type=static
は、スクリプトを /home/site/scripts にデプロイします。path
パラメーターを指定してください。 -
type=startup
は、スクリプトを Linux に startup.sh としてデプロイするか、Windows で startup.cmd します。 スクリプトは /home/site/scripts/ に展開されます。path
パラメーターは無視されます。 -
type=zip
は、.zip ファイルを /home/site/wwwroot に解凍します。path
パラメーターは省略可能です。
-
pom.xml ファイル内の
resourceGroup
要素とappName
要素の値を確認します。次のコマンドを使用して、
resourceGroup
とappName
の値を環境変数に割り当てます。export RESOURCE_GROUP_NAME=<resource-group> export WEB_APP_NAME=<app-name>
Jakarta EE アプリをコンパイルしてビルドする
Azure App Service のデプロイ設定を構成したら、次のコマンドを使用してソース コードをコンパイルしてパッケージ化します。
./mvnw clean package
次の出力が一般的です。
[INFO] --- war:3.4.0:war (default-war) @ jakartaee-app-on-jboss ---
[INFO] Packaging webapp
[INFO] Assembling webapp [jakartaee-app-on-jboss] in [/private/tmp/mslearn-jakarta-ee-azure/target/ROOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/private/tmp/mslearn-jakarta-ee-azure/src/main/webapp]
[INFO] Building war: /private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.881 s
[INFO] Finished at: 2025-02-21T06:32:30+09:00
[INFO] ------------------------------------------------------------------------
JBoss EAP on Azure App Service に Jakarta EE アプリをデプロイする
コードをコンパイルしてパッケージ化した後、次のコマンドを使用してアプリケーションをデプロイします。
./mvnw azure-webapp:deploy
成功メッセージとデプロイされたアプリケーションの URL を含む出力が表示されます。 後で使用するために、必ず URL を保存しておいてください。
データベース接続を構成する
サンプル アプリケーションは MySQL データベースに接続し、データを表示します。 pom.xml ファイルの Maven プロジェクト構成では、次の例に示すように MySQL JDBC ドライバーを指定します。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
その結果、JBoss EAP によって、デプロイ パッケージ ROOT.war に JDBC ドライバー ROOT.war_com.mysql.cj.jdbc.Driver_9_2
が自動的にインストールされます。
JBoss EAP で MySQL DataSource オブジェクトを作成する
Azure Database for MySQL にアクセスするには、JBoss EAP で DataSource
オブジェクトを構成し、ソース コードで Java Naming and Directory Interface (JNDI) 名を指定する必要があります。 JBoss EAP で MySQL DataSource
オブジェクトを作成するには、 /WEB-INF/createMySQLDataSource.sh スタートアップ シェル スクリプトを使用します。 次の例は、Azure App Service に既に存在する構成されていないバージョンのスクリプトを示しています。
#!/bin/bash
# In order to use the variables in CLI scripts
# https://access.redhat.com/solutions/321513
sed -i -e "s|.*<resolve-parameter-values.*|<resolve-parameter-values>true</resolve-parameter-values>|g" /opt/eap/bin/jboss-cli.xml
/opt/eap/bin/jboss-cli.sh --connect <<EOF
data-source add --name=JPAWorldDataSourceDS \
--jndi-name=java:jboss/datasources/JPAWorldDataSource \
--connection-url=${AZURE_MYSQL_CONNECTIONSTRING}&characterEncoding=utf8&sslMode=REQUIRED&serverTimezone=UTC&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin \
--driver-name=ROOT.war_com.mysql.cj.jdbc.Driver_9_2 \
--min-pool-size=5 \
--max-pool-size=20 \
--blocking-timeout-wait-millis=5000 \
--enabled=true \
--driver-class=com.mysql.cj.jdbc.Driver \
--jta=true \
--use-java-context=true \
--valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker \
--exception-sorter-class-name=com.mysql.cj.jdbc.integration.jboss.ExtendedMysqlExceptionSorter
exit
EOF
注
データソースを作成するときに、MySQL 接続のパスワードを指定しません。 環境変数 AZURE_MYSQL_CONNECTIONSTRING
は、 --connection-url
パラメーターで指定します。 この環境変数は、後でサービス接続が作成されるときに自動的に設定されます。
サービス接続の値は jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp
に設定され、パスワードなしで aad_jbossapp
ユーザー名が使用されます。
この URL に &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
を追加することで、 aad_jbossapp
ユーザーに対して Microsoft Entra ID 認証が有効になります。
次のコマンドを使用して、スタートアップ スクリプトを呼び出すように App Service インスタンスを構成します。
az webapp config set \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${WEB_APP_NAME} \
--startup-file '/home/site/scripts/startup.sh'
スクリプトの実行後、アプリケーション サーバーは、アプリケーション サーバーが再起動されるたびにスクリプトを呼び出します。
注
デプロイ成果物が ROOT.war でない場合は、 --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2
の値も変更します。
MySQL フレキシブル サーバーのサービス接続を構成する
スタートアップ スクリプトを構成した後、次の手順を使用して、MySQL フレキシブル サーバー接続に Service Connector を使用するように App Service を構成します。
次のコマンドを使用して環境変数を設定します。
export PASSWORDLESS_USER_NAME_SUFFIX=jbossapp export SOURCE_WEB_APP_ID=$(az webapp list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv) export MYSQL_ID=$(az mysql flexible-server list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv) export TARGET_MYSQL_ID=$MYSQL_ID/databases/world export MANAGED_ID=$(az identity list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv)
環境変数は、次の目的で使用されます。
-
PASSWORDLESS_USER_NAME_SUFFIX
は、MySQL フレキシブル サーバーへの接続に使用されるユーザー名のサフィックスです。 作成されたユーザー名には、プレフィックスaad_
の後に指定したサフィックスが付いています。 -
SOURCE_WEB_APP_ID
は、MySQL フレキシブル サーバーへの接続に使用される Azure App Service インスタンスの ID です。 -
MYSQL_ID
は MySQL フレキシブル サーバーの ID です。 -
TARGET_MYSQL_ID
は、world
データベースにアクセスする権限を持つユーザーとの接続を確立するための$MYSQL_ID/databases/world
としてデータベース名を指定します。 -
MANAGED_ID
は、MySQL フレキシブル サーバーへの接続に使用されるマネージド ID です。
-
serviceconnector-passwordless
の拡張機能を追加し、次のコマンドを使用してサービス接続を作成します。az extension add \ --name serviceconnector-passwordless \ --upgrade az webapp connection create mysql-flexible \ --resource-group ${RESOURCE_GROUP_NAME} \ --connection $PASSWORDLESS_USER_NAME_SUFFIX \ --source-id $SOURCE_WEB_APP_ID \ --target-id $TARGET_MYSQL_ID \ --client-type java \ --system-identity mysql-identity-id=$MANAGED_ID
注
Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present.
などのエラー メッセージが表示された場合は、数秒後にコマンドを再実行します。SQL プロンプトで、次のクエリを使用して、MySQL に登録されているユーザーの一覧を確認します。
SELECT user, host, plugin FROM mysql.user;
次の出力が一般的です。
+----------------------------------+-----------+-----------------------+ | user | host | plugin | +----------------------------------+-----------+-----------------------+ | aad_jbossapp | % | aad_auth | | azureuser | % | mysql_native_password | | $CURRENT_AZ_LOGIN_USER_NAME#EXT#@| % | aad_auth | | azure_superuser | 127.0.0.1 | mysql_native_password | | azure_superuser | localhost | mysql_native_password | | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | +----------------------------------+-----------+-----------------------+ 8 rows in set (2.06 sec)
aad_auth
プラグインを使用するaad_jbossapp
ユーザーが表示されます。 Azure にデプロイされた JBoss EAP から、パスワードなしでaad_jbossapp
ユーザー名を使用して MySQL フレキシブル サーバーに接続できます。
コード内の DataSource 参照を確認する
アプリケーションから MySQL データベースにアクセスするには、アプリケーション プロジェクトでデータ ソース参照を構成する必要があります。
データベース アクセス コードは、Java Persistence API (JPA) を使用して実装されます。
DataSource
参照の構成は、JPA 構成ファイル persistence.xmlにあります。
DataSource
参照を確認するには、次の手順に従います。
src/main/resources/META-INF/persistence.xml ファイルを開き、
DataSource
名が構成で使用されている名前と一致するかどうかを確認します。 スタートアップ スクリプトでは、次の例に示すように、java:jboss/datasources/JPAWorldDataSource
として JNDI 名が既に作成されています。<persistence-unit name="JPAWorldDatasourcePU" transaction-type="JTA"> <jta-data-source>java:jboss/datasources/JPAWorldDataSource</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="hibernate.generate_statistics" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> </properties> </persistence-unit>
次の例に示すように、
PersistenceContext
ユニット名で MySQL データベースにアクセスします。@Transactional(REQUIRED) @RequestScoped public class CityService { @PersistenceContext(unitName = "JPAWorldDatasourcePU") EntityManager em;
アプリケーションへのアクセス
サンプル アプリケーションは、3 つの REST エンドポイントを実装します。 アプリケーションにアクセスしてデータを取得するには、次の手順に従います。
演習の概要
このユニットでは、アプリケーション REST エンドポイントを検証し、アプリケーションが MySQL データベースからデータを取得できることを確認しました。 次のユニットでは、サーバー ログを調べます。