今更ながら、WildFly Maven Pluginを使うと、WildFlyにMavenプロジェクトからデプロイできることを
知りました…。
WildFly Maven Plugin – Introduction
JenkinsからWildFlyへのリモートデプロイ(pom.xmlの更新) - そごうソフトウェア研究所
wildfly-maven-pluginを使ったintegration test
見れば、デプロイ、アンデプロイ以外にも、WildFlyを起動したりとけっこういろいろできるみたいです。
いつも「standalone/deployments」ディレクトリにコピーしてたり、管理CLIからdeployコマンドでデプロイ
してたりしたので、あんまり気にしていませんでした…。
ちょっとしたエントリから、同じプラグインでInfinispan Serverにもデプロイできることを知ったので、
これを機に試してみましょう。
WildFlyに、WildFly Maven Pluginを使ってデプロイする
それでは、WildFlyにデプロイするための簡単なJava EEアプリケーションを作成します。
なお、WildFlyはダウンロード&展開&起動済みとします。管理用のユーザーだけ、先に作っておきましょう。
$ bin/add-user.sh -u wildfly-admin -p wildfly-password
ユーザーは、 wildfly-admin / wildfly-password とします。また、WildFlyは「172.17.0.2」で動作している
ものとします。ここに、別のサーバーからデプロイします。
pom.xmlの設定。プラグインのところは、あとで書きます。project.artifactIdは、「simple-ee-app」とします。
<packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <failOnMissingWebXml>false</failOnMissingWebXml> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <!-- あとで --> </plugin> </plugins> </build>
簡単なJAX-RSアプリケーションを作成。
src/main/java/org/littlewings/simple/ee/JaxrsActivator.java
package org.littlewings.simple.ee; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("") public class JaxrsActivator extends Application { }
src/main/java/org/littlewings/simple/ee/HelloResource.java
package org.littlewings.simple.ee; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "Hello World!!"; } }
で、これでパッケージングすればWARファイルができあがりますと。
$ mvn package ... $ ls -l target/simple-ee-app.war -rw-rw-r-- 1 xxxxx xxxxx 3688 4月 11 22:29 target/simple-ee-app.war
デプロイする
このWARファイルをデプロイするには、「mvn wildfly:deploy」を実行します。
プラグインの設定は、このようにしました。
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>1.2.0.Alpha4</version> <configuration> <hostname>172.17.0.2</hostname> <username>wildfly-admin</username> <password>wildfly-password</password> </configuration> </plugin>
「hostname」のデフォルト値はlocalhostだったりするので、ローカルでWildFlyにデプロイする場合は特に指定する
必要はありません。
各設定項目は、こちらを参照のこと。
WildFly Maven Plugin – wildfly:deploy
では、実行。
$ mvn wildfly:deploy
こんな感じに表示されれば、デプロイは成功しています。
4 11, 2017 10:33:32 午後 org.xnio.Xnio <clinit> INFO: XNIO version 3.5.0.Beta2 4 11, 2017 10:33:32 午後 org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.5.0.Beta2 4 11, 2017 10:33:33 午後 org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version 5.0.0.Beta18 4 11, 2017 10:33:33 午後 org.wildfly.security.Version <clinit> INFO: ELY00001: WildFly Elytron version 1.1.0.Beta24 [INFO] Authenticating against security realm: ManagementRealm [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 02:36 min [INFO] Finished at: 2017-04-11T22:33:42+09:00 [INFO] Final Memory: 20M/240M [INFO] ------------------------------------------------------------------------
WildFly側にもデプロイのログが出力されています。
2017-04-11 13:33:37,532 INFO [org.jboss.as.repository] (management-handler-thread - 4) WFLYDR0001: Content added at location /opt/wildfly/standalone/data/content/03/274be09c16dbf174b627a0b5e4b1e5929f0b2e/content 2017-04-11 13:33:37,577 INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) WFLYSRV0027: Starting deployment of "simple-ee-app.war" (runtime-name: "simple-ee-app.war") 2017-04-11 13:33:41,590 INFO [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool -- 70) RESTEASY002225: Deploying javax.ws.rs.core.Application: class org.littlewings.simple.ee.JaxrsActivator 2017-04-11 13:33:41,671 INFO [org.hibernate.validator.internal.util.Version] (ServerService Thread Pool -- 70) HV000001: Hibernate Validator 5.2.4.Final 2017-04-11 13:33:42,465 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 70) WFLYUT0021: Registered web context: /simple-ee-app 2017-04-11 13:33:42,504 INFO [org.jboss.as.server] (management-handler-thread - 4) WFLYSRV0010: Deployed "simple-ee-app.war" (runtime-name : "simple-ee-app.war")
ちなみに、「mvn wildfly:deploy」は「mvn package」もやってしまうので、実はパッケージングせずに
「mvn wildfly:deploy」だけでもよかったりします。
パッケージングをスキップしてデプロイだけをしたい場合は、「mvn wildfly:deploy-only」を実行すればOKです。
WildFly Maven Plugin – wildfly:deploy-only
$ mvn wildfly:deploy-only
1度デプロイしたあとは管理CLIのdeployコマンドの場合はアンデプロイするか「force」オプションを使わないと
デプロイできないのですが、このプラグインの場合は「force」がデフォルトでtrueなので、そのまま再デプロイ
可能だったりします。
redeployとか、redeploy-onlyもありますけどね。
WildFly Maven Plugin – wildfly:redeploy
WildFly Maven Plugin – wildfly:redeploy-only
ところで、終了時に時々ClassNotFoundExceptionが出るんですけど…。
Exception in thread "Remoting "management-client" task-11" java.lang.NoClassDefFoundError: org/xnio/XnioWorker$2 at org.xnio.XnioWorker.shutDownTaskPool(XnioWorker.java:769) at org.xnio.nio.NioXnioWorker.shutdown(NioXnioWorker.java:277) at org.jboss.remoting3.EndpointImpl.finishPhase1(EndpointImpl.java:254) at org.jboss.remoting3.EndpointImpl.closeTick1(EndpointImpl.java:237) at org.jboss.remoting3.EndpointImpl.access$200(EndpointImpl.java:92) at org.jboss.remoting3.EndpointImpl$TrackingExecutor.finishWork(EndpointImpl.java:832) at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:819) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.ClassNotFoundException: org.xnio.XnioWorker$2 at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239) ... 10 more
それでもふつうに動いてはいそうですが。
Infinispan Serverにデプロイする
同じWildFly Maven Pluginで、Infinispan ServerにRemote Taskをデプロイすることもできます。
こちらも、Infinispan Serverはダウンロード&展開&起動済みとします。
管理ユーザーは追加しておきます。
$ bin/add-user.sh -u ispn-admin -p ispn-password
依存関係とWildFly Maven Pluginの設定は、こちら。Infinispan Serverは、WildfFlyと同じく「172.17.0.2」で動作しているものとします。
というか、設定はほぼ同じです。
<dependencies> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-tasks-api</artifactId> <version>9.0.0.Final</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>1.2.0.Alpha4</version> <configuration> <hostname>172.17.0.2</hostname> <username>ispn-admin</username> <password>ispn-password</password> </configuration> </plugin> </plugins> </build>
なお、Infinispan ServerのRemote TaskのパッケージングはJARになります。アーティファクト名は「remote-task-wildfly-deploy」とし、
これがそのままJARファイルの名前になります。
では、サンプル敵にRemote Taskを作成します。
src/main/java/org/littlewings/infinispan/task/HelloTask.java
package org.littlewings.infinispan.task; import org.infinispan.tasks.ServerTask; import org.infinispan.tasks.TaskContext; public class HelloTask implements ServerTask<String> { @Override public void setTaskContext(TaskContext taskContext) { // no-op } @Override public String getName() { return "hello-task"; } @Override public String call() throws Exception { return "Hello World!!"; } }
Service Providerでの設定にも記載。
src/main/resources/META-INF/services/org.infinispan.tasks.ServerTask
org.littlewings.infinispan.task.HelloTask
あとは「mvn wildfly:deploy」でWildFlyと同様にデプロイできます。
$ mvn wildfly:deploy
その他は一緒なので割愛しますが、こちらは確認もしておきましょう。
テストコードで確認することにします。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.6.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-client-hotrod</artifactId> <version>9.0.0.Final</version> <scope>test</scope> </dependency>
こんな感じで。
src/test/java/org/littlewings/infinispan/task/HelloTaskTest.java
package org.littlewings.infinispan.task; import java.util.Collections; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; public class HelloTaskTest { @Test public void callServerTask() { RemoteCacheManager cacheManager = new RemoteCacheManager(new ConfigurationBuilder().addServer().host("172.17.0.2").port(11222).build()); try { RemoteCache<String, String> cache = cacheManager.getCache("default"); String result = cache.execute("hello-task", Collections.emptyMap()); assertThat(result).isEqualTo("Hello World!!"); cache.stop(); } finally { cacheManager.stop(); } } }
できましたと。
まとめ
WildFly Maven Pluginを使って、WildFlyにJava EEアプリケーション、Infinispan ServerにRemote Taskをデプロイしてみました。
そもそもプラグインに気づいていなかったのと、Infinispan Serverにもデプロイできるのが割と衝撃的でした。まあ、ベースが
WildFlyだから確かに…という感じではありますが、発想がなかったです…。
気づくきっかけになったのは、こちらのブログエントリでした。いやー、知っておいてよかったです。
Infinispan: In Memory Data Grid Patterns Demos from Devoxx France!
Infinispan ServerへのRemote Taskのデプロイで使ったソースコードについては、こちらに置いています。
https://github.com/kazuhira-r/infinispan-getting-started/tree/master/remote-task-wildfly-deploy