OpenLiberty Starterで作成してダウンロードしたMavenプロジェクトをカスタマイズし,実際に利用するLibertyの環境を構築するための,各種カスタマイズ方法を紹介します。
プラグインをExtensionとして組み込み(基本)
Liberty Maven pluginをMavenプロジェクトに組み込むと,liberty:devをはじめとしたLiberty環境を操作する多くのGoalが利用できるようになります。ですが,デフォルトではこれらは標準のGoalであるcompileやpackageなどでは実行されず,直接呼び出す必要があります。
Liberty Maven pluginをextensionとして組み込むことで,packagingタイプとしてliberty-assemblyを利用できるようになります。この状態では,標準の各GoalでLiberty Maven pluginのGoalが自動的に実行されるようになります。また,package Goalでは,他の環境にも導入可能な,アプリケーション・構成・Libertyランタイム全体を含んだZIPファイルが作成されます。
少し長いですが,ファイル全体を以下に載せます。これがカスタマイズの基本となります。
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.foobar</groupId>
<artifactId>foo-bar-app</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 成果物をliberty-assemblyに -->
<packaging>liberty-assembly</packaging>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>foo-bar-app</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<!-- extensionとして組み込む -->
<extensions>true</extensions>
<!-- 作成されるZIPに,最小限のFeatureだけ含める -->
<configuration>
<include>minify</include>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
このMavenプロジェクトでできる主なこと
-
liberty:devGoalを実行することで,アプリのコンパイル,Liberty環境の導入と構成ファイルの追加,アプリのデプロイが実行され,開発者モードでLibertyが起動する。Ctrl+Cを押すと終了する。Libertyの起動中にアプリのコードを変更すると,自動的に再コンパイル・再デプロイがおこなわれ,変更が反映される。 -
packageGoalを実行することで,他の環境に導入可能なZIPが生成される。
利用するLibertyランタイムを指定する
デフォルトでは,Open Libertyの最新版がダウンロードされてLiberty環境が構築されます。これを,特定のバージョンを指定したり,製品版のWebSphere Libertyにかえたりすることができます。
特定のバージョンのOpen Libertyを利用する
プラグインの<configuration>に,<runtimeArtifact>でOpen LibertyのArtifact IDとバージョンを記述します。
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<!-- 利用するランタイムをOpen Liberty v25.0.0.12に固定 -->
<runtimeArtifact>
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>25.0.0.12</version>
</runtimeArtifact>
</configuration>
</plugin>
製品版のWebSphere Libertyを利用する
Open LibertyとWebSphere Libertyは,バージョンが完全に同期されており,新機能も同時に提供されます。Open Libertyにのみ存在する機能も無いので,Open LibertyのMavenプロジェクトは,ランタイムを製品版に変えてもそのまま動きます。
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<!-- 利用するランタイムを製品版のWebSphere Libertyに -->
<runtimeArtifact>
<groupId>com.ibm.websphere.appserver.runtime</groupId>
<artifactId>wlp-kernel</artifactId>
<version>25.0.0.12</version>
</runtimeArtifact>
</configuration>
</plugin>
WebSphere Libertyには,何にでも使える「全部入り」のArtifactが(大きすぎて)存在しないので,Featureの入っていないカーネルのみのArtifact(wlp-kernel)を指定しています。必要なFeatureは,自動的に実行されるliberty:install-feature Goalで追加導入されます。
ここで導入されるWebSphere Libertyは,開発者用途などで無料で使用できるILAN版です。単独の開発者が専有して利用するPCなどの環境で利用している範囲では,ライセンス料は発生しません。
[INFO] [監査 ] CWWKE0001I: サーバー defaultServer が起動されました。
[INFO] [監査 ] CWWKE0100I: この製品は、開発使用向け、および限定的な実動使用向けにライセンスが交付されています。 全ライセンス条項は以下で表示可能です: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/license/base_ilan/ilan/25.0.0.12/lafiles/ja.html
一方で,複数の開発者で共有される開発サーバーや,本番環境での利用にあたっては,WebSphere Libertyにライセンスを適用し,IPLA版にすることが必要です。IPLA版の利用には,ライセンスの契約が必要となります。
WebSphere Libertyへのライセンスの適用
IBMと必要な契約を結ぶと,WebSphere LibertyのFixpackのサイトなどから,ライセンスファイル(wlp-base-license.jarなどを)をダウンロードする事ができるようになります。ダウンロードには,登録したIBM IDでログインしている必要があります。
このライセンスファイルを,Mavenでビルドを行う環境に,適当なArtifact ID(ここではcom.ibm.websphere.license / wlp-base-license / 1.0)で登録しておきます。
$ mvn install:install-file -Dfile=wlp-base-license.jar \
-DgroupId=com.ibm.websphere.license \
-DartifactId=wlp-base-license \
-Dversion=1.0
その後,<configuration>に<licenseArtifact>を追加し,上記のArtifact IDを指定すると,ライセンスが適用されたWebSphere Libertyを利用することができます。
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<runtimeArtifact>
<groupId>com.ibm.websphere.appserver.runtime</groupId>
<artifactId>wlp-kernel</artifactId>
<version>25.0.0.12</version>
</runtimeArtifact>
<!-- ライセンスファイルを適用する -->
<licenseArtifact>
<groupId>com.ibm.websphere.license</groupId>
<artifactId>wlp-base-license</artifactId>
<version>1.0</version>
</licenseArtifact>
</configuration>
</plugin>
ただ,これではliberty:devでローカルでテストを行う際にもIPLA版が使用されるようになってしまいます。これは好ましくないので,ライセンスの登録は別途プロファイルを作成し,その中で構成するとよいでしょう。
<profiles>
<profile>
<id>for-dev</id>
<!-- 何も指定しなければこちらが使われる -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>build-ipla</id>
<!-- -Pbuild-ipla が指定されたときの追加設定 -->
<build>
<plugins>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<configuration>
<!-- ライセンスファイルを適用する -->
<licenseArtifact>
<groupId>com.ibm.websphere.license</groupId>
<artifactId>wlp-base-license</artifactId>
<version>1.0</version>
</licenseArtifact>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
これにより,以下のように-Pbuild-iplaを指定して実行したときのみ,ライセンスが適用されるようになります(既存のILAN版環境が残っていると上手くいかなことがあるので,cleanも追加しています)。
$ mvn clean package -Pbuild-ipla
Libertyのフットプリントを軽くする
スターターからダウンロードしたLibertyのMavenプロジェクトは,server.xmlで,Java EE/Jakarta EEなどのFeatureが全て有効になった状態で構成されています。
<!-- Enable features -->
<featureManager>
<feature>jakartaee-10.0</feature>
</featureManager>
実際にLibertyを起動してみると,なんと41ものFeatureが有効になった状態で起動してきます。
[INFO] [監査 ] CWWKF0012I: サーバーは次のフィーチャーをインストールしました。[appAuthentication-3.0, appAuthorization-2.1, appClientSupport-2.0, appSecurity-5.0, batch-2.1, beanValidation-3.0, cdi-4.0, concurrent-3.0, connectors-2.1, distributedMap-1.0, enterpriseBeans-4.0, enterpriseBeansHome-4.0, enterpriseBeansLite-4.0, enterpriseBeansPersistentTimer-4.0, enterpriseBeansRemote-4.0, expressionLanguage-5.0, faces-4.0, jakartaee-10.0, jdbc-4.2, jndi-1.0, jsonb-3.0, jsonp-2.1, mail-2.1, managedBeans-2.0, mdb-4.0, messaging-3.1, messagingClient-3.0, messagingSecurity-3.0, messagingServer-3.0, pages-3.1, persistence-3.1, persistenceContainer-3.1, restfulWS-3.1, restfulWSClient-3.1, servlet-6.0, ssl-1.0, transportSecurity-1.0, webProfile-10.0, websocket-2.1, xmlBinding-4.0, xmlWS-4.0]。
また,この状態では,パッケージしたZIPファイルのサイズは110Mバイトを超えています。
LibertyのFeatureの一覧を元に,アプリケーションやサーバーで必要なFeatureだけにしぼることにより,Libertyのフットプリント,つまりメモリサイズや起動時間,導入サイズを大幅に削減することが可能です。
たとえば,server.xmlを以下のように変更します。
<!-- Enable features -->
<featureManager>
<feature>restfulWS-3.1</feature>
<feature>jsonb-3.0</feature>
<feature>cdi-4.0</feature>
<feature>persistence-3.1</feature>
<feature>transportSecurity-1.0</feature>
</featureManager>
これにより,有効になるFeatureを11にまで減らすことができます。
[INFO] [監査 ] CWWKF0012I: サーバーは次のフィーチャーをインストールしました。[cdi-4.0, jdbc-4.2, jndi-1.0, jsonb-3.0, jsonp-2.1, persistence-3.1, persistenceContainer-3.1, restfulWS-3.1, restfulWSClient-3.1, ssl-1.0, transportSecurity-1.0]。
作成されるパッケージされたZIPファイルのサイズも,60Mバイトまで減少します。
なお,pom.xmlの<dependencies>は,編集する必要はありません。ここを修正しても,フットプリントの減少には寄与しません。
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<dependencies>
アプリケーションやLibertyで利用する外部ライブラリを登録する
Libertyが利用するJDBCドライバーや,アプリケーションが利用する外部ライブラリなどの登録方法です。
アプリケーションが,内部(WEB-INF/libなどの場所)に取り込んで利用するライブラリは<dependencies>にデフォルトのスコープ(compile)で記述します。
Mavenのセントラルレポジトリに登録されているライブラリ
pom.xmlの<dependencies>に,追加したいライブラリのArtifact IDを指定します。<scope>はprovidedにしておきます。ここでは,Db2に接続するためのIBM Data Server Driver For JDBC and SQLJを登録しています。
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ibm.db2/jcc -->
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<version>12.1.2.0</version>
<scope>provided</scope>
</dependency>
<dependencies>
プラグインの<configuration>に<copyDependencies>を追加し,ファイルをLiberty環境にコピーします。<location>に指定された場所は,${server.config.dir}からの相対パスになります。
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<!-- ファイルをLiberty環境にコピー -->
<copyDependencies>
<dependencyGroup>
<location>resources/db2</location>
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
</dependency>
</dependencyGroup>
</copyDependencies>
</configuration>
</plugin>
server.xmlを編集し,このファイルを利用してライブラリを定義します。
<library id="db2jdbc_jar">
<!-- copyDependenciesでコピーしたファイルを参照 -->
<fileset dir="${server.config.dir}/resources/db2" includes="*.jar" />
</library>
セントラルレポジトリに登録されていないライブラリ
プロジェクトのローカルレポジトリとして登録してしまうのが簡単です。
Mavenプロジェクト内に,たとえばrepoというディレクトリを作成し,pom.xmlにローカルレポジトリとして登録します。
<repositories>
<repository>
<id>local-repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
追加するライブラリに適当なArtifact(ここではcom.mycompany / baz / 1.23.456)をつけ,repoの下にそのディレクトリを作成して,JARファイルを保存します。
これにより,ファイルがプロジェクトから<dependency>として参照できるようになります。
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>baz</artifactId>
<version>1.23.456</version>
</dependency>
あとは前項と同じようにLibertyにライブラリとしてコピーして,
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<!-- ファイルをLiberty環境にコピー -->
<copyDependencies>
<dependencyGroup>
<location>resources/baz</location>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>baz</artifactId>
</dependency>
</dependencyGroup>
</copyDependencies>
</configuration>
</plugin>
server.xmlでライブラリとして登録します。
<library id="baz_jar">
<!-- copyDependenciesでコピーしたファイルを参照 -->
<fileset dir="${server.config.dir}/resources/baz" includes="*.jar" />
</library>
これにより,例えばアプリケーションから外部ライブラリとして参照することができるようになります。
<!-- Configures the application on a specified context root -->
<webApplication contextRoot="/foo-bar-app" location="foo-bar-app.war">
<classLoader privateLibraryRef="baz_jar" />
</webApplication>
外部リソースへの接続(DB等)を構成する
JDBCドライバーのJARファイルをライブラリとして登録すると,それを利用してDB接続が構成できます。
<!-- Db2 access settings -->
<variable name="db2.servername" defaultValue="192.168.1.77" />
<variable name="db2.port" defaultValue="8200" />
<variable name="db2.database" defaultValue="LOCD5L2" />
<variable name="db2.user" defaultValue="LOCDADM" />
<variable name="db2.password" defaultValue="{xor}Gx1tDQwUGRQ=" />
<!-- Db2 data source -->
<dataSource jndiName="jdbc/db2DataSource" id="db2DataSource">
<!-- 定義したライブラリを利用してjdbcDriverを構成 -->
<jdbcDriver libraryRef="db2jdbc_jar" />
<containerAuthData user="${db2.user}" password="${db2.password}" />
<properties.db2.jcc databaseName="${db2.database}"
serverName="${db2.servername}" portNumber="${db2.port}"
connectionTimeout="15s"/>
</dataSource>
前項で作成したdb2jdbc_jarをlibraryRef属性で指定して<jdbcDriver>を定義し,それを利用して<dataSource>を定義しています。
認証データーや接続パラメーターが,<variable>で変数化されていることに注意してください。これにより,何も指定が無ければdefaultValue属性に指定した値が利用されますし,またこの値は環境変数などによって環境に応じて上書きすることができるようになります。
Libertyの実行を環境変数でカスタマイズする
上記のように,Libertyの構成ファイルserver.xml内では,${変数名}の形で変数を参照することができます。
変数としては,まずLiberty自身によって設定されている,Liberty内の各種ディレクトリ等をあわらすものがあり,例えば以下のようなものが利用できます。
-
${wlp.install.dir}- Libertyの導入ディレクトリ
-
${wlp.server.name}- 現在のサーバー名
-
${wlp.user.dir}- ユーザーの構成などが置かれるusrディレクトリ
- 変更していなければ
${wlp.install.dir}/usr
-
${server.config.dir}- サーバーの構成が置かれているディレクトリ
- 変更していなければ,
${wlp.user.dir}/servers/${wlp.server.name}
-
${server.output.dir}- ログや一時ファイルなどが生成されるディレクトリ
- 変更していなければ
${server.config.dir}と同じ
また,これら以外にもユーザー定義の変数が利用できます。定義は以下のような場所で可能で,上のものほど優先されます(一部省略)。
- Libertyを起動したときのコマンドライン引数での指定
-
server.xmlなどで設定された<variable>要素のvalue属性 - Javaのシステムプロパティ
-
bootstrap.propertiesファイルの設定 - 環境変数
-
server.xmlなどで設定された<variable>要素のdefaultValue属性
下に設定したものは,上のより優先度が高い設定で上書きすることができます。基本的には,利用する変数をserver.xml内の<variable>要素で定義し,変更したくないものをvalue属性に,環境に応じて変更したいものをdefaultValue属性に書きます。
環境変数の検索
例えば,${db2.database}という変数の値を環境変数から取得する際には,以下の順で検索されます。
-
db2.database- そのまま
-
db2_database- 英数字以外を
_に変換した名前
- 英数字以外を
-
DB2_DATABASE- さらに英字を大文字に変換した名前
環境変数の設定
Libertyに環境変数を渡すには,通常の,起動シェルでexport DB2_DATABASE=LOCD5L1のように設定してからコマンドを起動する他に,Libertyの構成ファイルによる設定も可能です。
${wlp.install.dir}/etcディレクトリを作成し,そこにserver.envというファイルを追加することで,そのLiberty環境で実行される全てのサーバープロセスで有効になります。
etcディレクトリは,基本的にはその環境でのみ有効な値,可搬性のない値を設定する目的で利用されていますので,Mavenプロジェクトで作成されるZIPには含めることができません。ZIPを展開したあとで,あらためてディレクトリとファイルを作成して配置します。
Kubernetes環境のSecretのように,秘密情報を環境変数のかたちで与えてプロセスを起動する仕組みが,最近は色々と出てきています。Libertyで使用するパスワードなどの認証情報も,これらの安全な方法でLibertyに提供するようにするとよいでしょう。
${wlp.install.dir}/etc/server.envに設定できる環境変数
このファイルには,いくつかの環境変数を設定することで,Libertyを通常とは異なる方法で起動することができるようになります。
-
JAVA_HOME- JDK/JREが導入されているディレクトリを指定します
- Libertyを起動するのに使用するJDK/JREを,システムのデフォルトJDKから変更することが可能です
-
WLP_USER_DIR- ユーザーの構成ファイルが置かれる
${wlp.user.dir}を,デフォルトから別の場所に変更します
- ユーザーの構成ファイルが置かれる
-
WLP_OUTPUT_DIR-
${server.output.dir}を,デフォルトから他の場所に変更します - 指定されたディレクトリに,サーバー名のディレクトリが追加で作成され,そこにログや一時ファイルなどが生成されます
-
アプリケーションのコードは管理せず,サーバーのみを管理する
ここまでのMavenプロジェクトでは,アプリケーションを実装するコードと,サーバーを設定するコードが一つのプロジェクト内に格納されていました。
ですが,多くの日本のお客様では,コードを開発しメンテナンスする部門と,サーバーの設定をメンテナンスする部門が分かれていることも多いかと思います。そのような場合,両者が一つのプロジェクト内に混在していると,都合が悪いことがあります。
その場合には,プロジェクトを分離し,サーバーの構成のみを管理するMavenプロジェクトを作成することもできます。ここでは,foo-bar-appとfoo-bar-serverの二つのプロジェクトに分離することにします。前者は普通のWARを作成するMavenプロジェクトにします。
両者を同じビルド環境でビルドし,アプリケーション側のMavenプロジェクトfoo-bar-appでmvn installを実行しておきます。これで他のプロジェクトから,成果物をArtifact IDで参照できるようになります(もしくは,利用しているローカルのレポジトリがあれば,そこにアプリケーションを登録します)。
サーバーのMavenプロジェクトfoo-bar-serverを以下のように作成します。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.foobar</groupId>
<artifactId>foo-bar-server</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>liberty-assembly</packaging>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- サーバーで実行するアプリをdependencyとして登録 -->
<dependency>
<groupId>com.mycompany.foobar</groupId>
<artifactId>foo-bar-app</artifactId>
<version>1.2.345</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<finalName>foo-bar-server</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.11.5</version>
<extensions>true</extensions>
<configuration>
<include>minify</include>
<!-- dependenciesに指定されたwarをデプロイする -->
<deployPackages>dependencies</deployPackages>
<stripVersion>true</stripVersion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
利用するアプリを<dependencies>に定義します。<type>として,warやearを適切に設定します。
Liberty pluginの<configuration>に,<deployPackages>dependencies</deployPackages>を追加すると,アプリがLiberty環境にデプロイされるようになります。ファイルにバージョン番号がついていると構成が複雑になるので,stripVersion>true</stripVersion>をつけて削除しておきます。
アプリのコンパイルは行わないので,maven-war-pluginも削除します。プロジェクトのsrc/main/javaディレクトリも空っぽにしておきます。
次にserver.xmlを編集し,デプロイされたアプリケーションを有効にします。
<!-- Configures the application on a specified context root -->
<webApplication contextRoot="/foo-bar"
location="boo-bar-app.war" />
これでLibertyの環境を構築するプロジェクトができあがります。あとは,前項までの各種カスタマイズを行ってください。

