Payara 6 を使う

WildFly, TomEE ,GlassFish ときたので、ここは当然? payara にも手を出してみる。

インストール

公式ページのここから適当なバージョンの Payara をダウンロード。
今だと JakartaEE 10 対応の Ver6 系列が落とせるので、そいつの full の方をチョイス。
web profile もあるが、違いを解説できるほど詳しくはないので今回はスルー。

なお、環境は MacOS Monterey, java17 ですが、windows 環境でも同様の手順で起動〜簡単な動作確認はできるでしょう。

解凍すれば使えるようにはなっている。

問題は置き場所だが、多分、ほとんどの人がまずはお試しで使うと思うので、/usr/local ではなく、ユーザーホームの適当なフォルダに配置すればいいと思う。

/payara6/bin

に移動して

./asadmin start-domain

でまずは起動。

ブラウザで localhost:4848 にアクセスして、以下のような管理コンソール画面が表示されればまずは Payara のインストール自体は成功しています。

なんらかの事情でインストールした(ローカル)ホスト以外のマシンからアクセスするためにはパスワード設定を有効にする必要があります。

./asadmin change-admin-password

を実行して新しい管理者とそのパスワードを設定。その後

./asadmin enable-secure-admin

を実行して、再起動すれば、外部リモートマシンから管理コンソール画面にアクセスできるようになります。

上記設定が完了すると管理画面呼び出し時にパスワード入力を求められるようになります。

 

とりあえず簡単な war ファイルをデプロイしたいんだが、その前に・・・

Payara の port を変更

8080 ポートは、WildFly や Tomcat などで使用されている場合が多いと思うので、あらかじめ 80 に変更しておきたい。

これは上のコンソール画面から簡単に行える。

画面右のノードから configurations -> server-config -> Network Config -> Network Listners の順に展開。

下図の Port: 8080 のところを 80 に変更。

glassfish と同様にその場で変更できる。再起動不要。

実際、この状態で localhost:80 にアクセスすると

というウェブページが表示される。

ここらへん、Tomcat あたりと違う。

データベース(PotgreSQL)との連携

GlassFish の時と同様、

JDBC コネクションプールの作成→データリソースの作成

とすればいいです。

ただし、GlassFish の時と違うのはコネクションプールの作成より先に jdbc ドライバをコマンドラインから登録しておくこと。

Payara 起動後、コマンドラインから

asadmin add-library (path)/postgresql-(version).jar

と入力。

Command add-library executed successfully

と返ってくれば OK牧場です。

よくわからなければ公式のブログ記事(『Using PostgreSQL with Payara Server』)参照。

コネクションプールを作成して、ping を打った時に

と Ping Succeededとなれば、設定はうまくいってます。

GlassFish の時と同様、クラスパスの設定などは不要です。
設定がうまくいってないと「クラスパスを正しくセットしる」みたいなエラーメッセージは出るんですが、真にうけない方がいいでしょう。

簡単なウェブアプリで動作確認

今回も jpa-hibernate プロジェクトを使用。

なんですが、通常の書き方だと動作しません。

しばらくハマって頭上に?マークを浮かべてたんですが、これは Payara6 で hibernate を使う時に出現するバグのようです。

GitHub isuues でスレ立ってます。

解決方法は、そこにも書いてありますが、persistence.xml に

 (persitence.xml)
            <property name="hibernate.type.xml_format_mapper" value="jaxb"/>
            <property name="hibernate.type.json_format_mapper" value="jsonb"/>

の2行を追加することです。
しかし、この解決(最終的な解決ではないですが)方法が提示されたのは、この記事書いている4日前。

当方の JakartaEE 力もあがってきているなあと思うと同時に、自由を維持していくことはそれなりの労力がかかるんだということを痛感させられます。

バグについて

なお、このバグに興味を持って、Payara のソースコードを少し読んだんだが、内部的には JavaEE 8 的な処理があって、これはちょっと根が深いかな?とは思った。

WildFly の鬼のような分量のソースコードを読むのに比べれば、負担は少ないのかもしれないが、これに取り組むのは気が引ける。。。

バグ?

データベース名に database-1 などとハイフンを入れるとハイフン以下を無視して動作するようだ。

 

 

 

CDI と weld の関係

Java の習得は、SE → EE の順に進むと思うが、EE になって役者がごそっと出てくるため、躓きやすい。

これまでにも EJBJPA の話題は取り上げてきたが、今回は CDI 。

まず、CDI と weld の関係だが、CDI が仕様で weld がその実装の一つ。

WildFly の stanalone.xml などで

        <extension module="org.jboss.as.weld"/>

とあるのは、この WildFly には weld を組み込んでいますよ、という意味だ。

WildFly 27 では、weld 5.1 が採用されているので、その概略は

Weld 5.1.0.Final – CDI Reference Implementation

でチェックするといいだろう。

下手な日本語解説記事よりわかりやすい。

CDI とは?

ところで CDI とは何だろう?
よく依存性注入がどうしたこうしたと難しげに解説してあるサイトがあるが、初学者が理解できるとは思えない。
簡単に言えば、あるオブジェクトを使うのにいちいち new して作成せずともコンテナの方で勝手にやってくれる機能のことだ。

注入されるクラスにはそのインスタンスの生存期間を明示する必要があるので scope 関係のアノテーションを付与し、実際に注入する際には @Inject アノテーションでその箇所を明記する。

なお、CDI は Contexts and Dependency Injection の頭文字をつなげたもの。

サンプルコード解説

いつものように簡単なサンプル作成。

インジェクトされるクラスとインジェクトするクラス(サーブレット)を作成し、使用通りに動くか検証。

インジェクトされる側のクラスは以下の通り。

ScopedSevice.java
------
@RequestScoped
public class ScopedService {

    private int counter = 0;

    public void countUp() {
        this.counter++;
    }

    public int getCounter() {
        return this.counter;
    }
}

これを以下のサーブレットクラスにインジェクトする(今回はフィールドにそのままインジェクト)する。

CDI.java
-------
public class CDI extends HttpServlet {

    @Inject
    ScopedService scopedService;

    @Override
    protected void doGet(final HttpServletRequest pReq, final HttpServletResponse pResp) throws ServletException, IOException {
        this.scopedService.countUp();
        this.scopedService.countUp();
        pResp.setContentType("text/plain");
        pResp.getWriter().println("Counter Value -> " + this.scopedService.getCounter());
    }
}

ScopedService クラスは new などで明示的にインスタンス化されていないが、CDI クラスから問題なく使えるか試すコードです。
インジェクトされた後、countUp メソッドを2回呼び出しているので、counter = 2 となっていれば、良いわけです。
サーブレットなので、ブラウザから呼び出すと

と見事に予想通りの処理をしてくれています。

ソースコードは github にあげてあります。

面白かったのは、Inject される側のクラスで @Singleton を使うと以下のようなエラーが出た点だ。

Dispatcher error: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"CDI-Jakarta10-1.0.war\".WeldStartService" => "Failed to start service
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ScopedService with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject servlet.CDI.scopedService
at servlet.CDI.scopedService(CDI.java:0)
"}}

CDI を使う利点の一つは、スコープの管理が楽になることなので、安直に singleton は使わない方がいいのかもしれません。

参考

ここ

Unfortunately, there’s a little problem with this pseudo-scope. Beans with scope @Singleton don’t have a proxy object.

CDI の仕様が変われば、うまく扱えなくなること確実なアノテーション。それが @Singleton www

 

Jakarta EE 10 時代到来か? WildFly 27, GlassFish 7, Payara 6

WildFly 27

WildFly 27 がリリースされた。

WildFly 27 では、JakartaEE 10 のみの対応となるので、今後は本格的に JakartaEE 10 の時代となりそう。

気になる JakartaEE 9.1 → 10 に伴う仕様の変更は、ざっくりいうと以下の図のような感じ。

CDI 関連が大幅変更。CDI Lite 4.0 (橙色)が新規に追加され、従来の CDI も 4.0 にアップデートされた。
ここらへんはわかりにくいところなので、『CDI と weld の関係』にまとめる予定。

他の仕様もかなりの部分がアップデート(青色)されている。

Servlet が 6.0 になっているのに恐怖を感じるが(笑)、そろそろ移行作業を開始しましょうかね。

GlassFish 7

GlassFish も JakartaEE 10 に対応した GlassFish 7 をリリースしている。

JakartaEE 10 環境、整ってきました。

ただし、

NOTE: The latest milestone version doesn’t provide Admin Console (GUI for administering the server). This will be fixed in the final version of GlassFish 7.

ということなので、現在配布されているバージョン(M8)はウェブアプリを GUI コンソール画面からデプロイすることはできない

実際、起動後 loalhost:4848 にアクセスしても以下の画面から進まない。

どうしても使いたい場合は、github リポジトリからソースを取ってきて自力でビルドするしかないだろう。

ただし、ビルド産物は M7 で、これが本当に JakartaEE 10 に対応しているかどうかは不明。

Payara 6

Payara 6 はコミュニティ版も Jakarta EE 10 に対応しているらしい。

payara は気にはなっていたのだが、触ったのは今回が初めて。

しかし、GlassFish とまるっきり一緒だと思っていたのだが、コンソール画面も微妙にカスタマイズ入ってますね。

ブログの記事なども充実しており、乗り換えてもいいかも。

まとめ

JakartaEE 10 対応のアプリケーションサーバーも出揃ってきた。

特に payara に好印象を持った。

今回は、アプリケーションサーバーの紹介程度になってしまったので、JakartaEE 10 の仕様・使い方に関しては順次別記事にまとめていく予定。

 

 

 

M1/M2 Mac で eclipse を使う

M1 Mac で Java 開発用に eclipse を導入しようとあちこち調べたのだが、なんか筋悪の指南が多いのでメモ的にまとめ。

筋悪というのは、「eclipse の日本語版は Intel Mac 向けしかないので、それを使いましょう」的なものがほぼ全てだったから。

そんなに日本語化って重要?

多くのユーザーがいると思われる Pleiades All in One (いわゆる eclipse の日本語版)は、確かに現時点(2022/11)では Intel Mac 向けのバージョンしか上がってないのだが、公式サイトには既に M1/M2 向けのコンパイル済み eclipse がダウンロード可能になっているから。

ここで Download AArch64 を選べば、apple シリコン向けの eclipse のダウンロードが始まります。

思うに、Pleiades のは、ちょっとやり過ぎているところがあって、例えばマルチユーザー環境でこのバージョンを使うとたぶんアプリ自体が落ちます(少なくとも私の環境では落ちた)。

一方、こちらのバージョンは、JRE のバージョンやインストール先の指定もできるので、自分のホームにインストールしておけば、他のユーザーに迷惑をかけずに使えます。しかも arm ネイティブで。

Hello, eclipse

インストールが済んだら、まずはハロワ的なやつ。

今回は maven プロジェクトをチョイス。

今回は pom.xml の中身は手動で設定したが、多分、もっと上手いやり方もあるんだろう。

いつものコードを実装して run 。

コンソール出力に

Hello, eclipse

と出て、まずは一安心。

 

(続く)

 

Java 8 → 11, 17 あたりへの移行(migration)

以前に JavaEE → JakartaEE の移行に関する記事を書いたが、この手の情報が必要な人はおそらく Java8 → Java11 and/or Java17 の移行に関する情報も必要なんでは?と思う。

「Java8 migration」あたりで検索するとそれこそ山のように移行案内系の記事は出てくる。

なのだが、

Java 8 から Java 11 にコードを移行するための万能のソリューションはありません

Java 8 から Java 11 への移行

とあるように、移行作業は機械的にできるものではなさそう。

マイクロソフトの中の人が言うくらいだから、まあ、そういうことなんでしょう。

ここは「急がば回れ」式でいった方がいいところでしょうか。

ということで、Java8 以降で起こった Java 文法上の主要な変化。

module

Java9 から package の上位概念として module が導入された。

(続く)