CLOVER🍀

That was when it all began.

PayaraをEmbeddedなサーバーとして使う

Payaraといえば、Payara Microを使ってjava -jarから実行したり、ふつうにPayara Serverにデプロイして使ったり…という
感じの使い方をすると思いますが、そういえばGlassFishの頃からEmbeddedにも使えるという話を最近思い出しました。

GlassFishの頃にも使ったことがなかったのと、ちょっと興味もあったので試してみることにしました。

参考にしたのは、こちら。

Using Payara Embedded & Payara Micro with Maven

GlassFish v3.1で組込み用のAPIが変わった? - 裏紙

Payara MicroProfile 1.0 (ja) - notepad

準備

用意したpomは、こんな感じ。
pom.xml

<?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>org.littlewings</groupId>
    <artifactId>payara-embedded</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <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>fish.payara.extras</groupId>
            <artifactId>payara-embedded-web</artifactId>
            <version>4.1.2.172</version>
        </dependency>
        <dependency>
            <groupId>fish.payara.api</groupId>
            <artifactId>payara-api</artifactId>
            <version>4.1.2.172</version>
        </dependency>
    </dependencies>

    <build>
        <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
    </build>
</project>

Payaraを組み込みで動かすには、「payara-embedded-web」か「payara-embedded-all」が必要です。また、「payara-api」も
別途追加しましょう。

「web」と「all」はProfileの違いだと思いますので、必要な方で。今回は「web」を選びました。

packagingは、「war」です。

あと、コンパイル結果などは「src/main/webapp/WEB-INF/classes」にするようにしておきました。

    <build>
        <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
    </build>

これで、かなりハマりました…。

サンプルのJava EEアプリケーション

動作確認用のサンプルは、簡単なJAX-RSのコードで。

JAX-RSの有効化。
src/main/java/org/littlewings/payara/JaxrsActivator.java

package org.littlewings.payara;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("")
public class JaxrsActivator extends Application {
}

テスト用のJAX-RSリソースクラス。
src/main/java/org/littlewings/payara/EchoResource.java

package org.littlewings.payara;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@Path("echo")
public class EchoResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String echo(@QueryParam("message") String message) {
        return "Message: " + message + "!!" + System.lineSeparator();
    }
}

起動クラス

最後に、Payaraを組み込みで起動するためのコードです。
src/main/java/org/littlewings/payara/App.java

package org.littlewings.payara;

import java.nio.file.Paths;

import org.glassfish.embeddable.BootstrapProperties;
import org.glassfish.embeddable.GlassFish;
import org.glassfish.embeddable.GlassFishException;
import org.glassfish.embeddable.GlassFishProperties;
import org.glassfish.embeddable.GlassFishRuntime;

public class App {
    public static void main(String... args) {
        try {
            BootstrapProperties bootstrap = new BootstrapProperties();
            GlassFishRuntime runtime = GlassFishRuntime.bootstrap(bootstrap);
            GlassFishProperties properties = new GlassFishProperties();
            properties.setPort("http-listener", 8080);

            GlassFish glassfish = runtime.newGlassFish(properties);
            glassfish.start();

            glassfish
                    .getDeployer()
                    .deploy(Paths.get("src/main/webapp").toFile(),
                            "--contextroot",
                            "/",
                            "--name",
                            "sample");

            // glassfish.stop();
            // glassfish.dispose();
        } catch (GlassFishException e) {
            e.printStackTrace();
        }
    }
}

GlassFishの頃のコードのままみたいです。

今回は待ち受けポートを8080に、

            properties.setPort("http-listener", 8080);

公開するパスを「src/main/webapp」、コンテキストパスを「/」としました。

            glassfish
                    .getDeployer()
                    .deploy(Paths.get("src/main/webapp").toFile(),
                            "--contextroot",
                            "/",
                            "--name",
                            "sample");

デプロイは、GlassFish#startの後にやるみたいですね。

停止は、GlassFish#stopおよびGlassFish#disposeだと。

            // glassfish.stop();
            // glassfish.dispose();

stopしても、disposeしなければ再度startが可能だとか。

あと、今回の例だと「src/main/webapp」配下に「WEB-INF/classes」がないとクラスを認識しなかったので、今回は
「src/main/webapp」で参照するパスの配下にコンパイル後の結果などを出力しておきました。

            glassfish
                    .getDeployer()
                    .deploy(Paths.get("src/main/webapp").toFile(),
                            "--contextroot",
                            "/",
                            "--name",
                            "sample");

これが、pom.xmlに以下の記述が入っていた理由です。

    <build>
        <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
    </build>

あとは、用意したmainメソッドを持つクラスを起動すればOKです。

動作確認。

$ curl http://localhost:8080/echo?message=HelloWorld
Message: HelloWorld!!

OKそうですね。

Payara Microがあるので、それほど出番はないかもしれませんが、知識として覚えておくとしましょう。