JSF 2.3 では新しい機能として Websocket が追加されます。
JSF 2.3 はまだリリースされていませんが、先日 JSF 2.3-m09 が公開されたので、
これを使って Websocket を試してみようと思います。
環境
- macOS Sierra
- Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
- WildFly 10.1.0.Final
- Payara Server 4.1.1.164
はじめに
今回やったことは下記に書いてあることそのままです。
http://blog.payara.fish/jsf-2.3-the-websocket-quickstart-under-payara-server
ボタンをクリックすることでサーバサイドから時間を取得してそれを表示するアプリを作ります。 アプリの作り方は上記サイトを見てもらえばわかると思うので、ここでは上記のサイトには書かれていない、 JavaEE8に対応していない現状のAPサーバで JSF 2.3 を有効にする方法について説明します。
WildFly 10.1.0.Final で試す
まず、普段利用している WildFly で動かそうとしてみました。
WildFly で JSF 2.3 を有効にするためには、WildFly が内包する JSF を無効にする必要があります。
無効にする方法は、下記の記述をした WEB-INF/jboss-deployment-structure.xml
を用意します。
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="jsf"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
JSF 2.3 の jar ファイルは WEB-INF/lib
フォルダに配置します。
この状態で WildFly にデプロイし、表示した画面でボタンをクリックすると下記のエラーが発生してしまいます。
Caused by: javax.faces.el.EvaluationException: javax.el.PropertyNotFoundException: /index.xhtml @15,73 action="#{pushBean.clockAction}": Target Unreachable, identifier 'pushBean' resolved to null
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:94)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
ApplicationScoped を付与した PushBean クラスがインスタンス化されていないようです。 スコープを変えたり、色々試してみたのですが動作は変わらないので諦めました。 動かす方法をご存知でしたら教えて頂けると嬉しいです。
Payara Server で試す
参考にしたサイトは Payara を使っているので、次に Payara で試してみることにしました。 Payara も JSF を内包しているので何もせずにデプロイすると下記エラーが発生します。
Caused by: java.lang.reflect.MalformedParameterizedTypeException
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:58)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:51)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:92)
at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:140)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:90)
at java.lang.Class.getGenericSuperclass(Class.java:777)
at javax.enterprise.util.TypeLiteral.getTypeParameter(TypeLiteral.java:103)
at javax.enterprise.util.TypeLiteral.getType(TypeLiteral.java:66)
at com.sun.faces.cdi.CdiUtils.<clinit>(CdiUtils.java:76)
... 65 more
Payara が内包する JSF を無効にする方法がわからなかったのですが、
Payara の場合は視点が違っていて、内包する JSF を無効にするのではなく、
Bundle した JSF を有効にする設定をしなければならないようです。
Bundle した JSF を有効にする方法は下記の記述をした WEB-INF/glassfish-web.xml
を用意します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC
"-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN"
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<class-loader delegate="false" />
<property name="useBundledJsf" value="true" />
</glassfish-web-app>
まとめ
設定さえわかれば何も難しい話ではなかったんですが、 設定方法がわからなくて時間がかかってしまいました。 特に Payara の方は全然情報が見つからなくて苦戦…。 基本的にはリリースされてJavaEE8対応されたAPサーバで動かすことになるので知らなくても問題ないわけですが、 早期に試そうとすると色々とハードルがあり大変です。まあそれが楽しかったりするんですけどね。