JSF の HelloWorldを作ってLibetyで試す

# 目的

LibertyのJSF環境を構築して HelloWorld のような簡単なプログラムでテストします。

# JSFプログラムの説明

EclipseでDynamic Web Projectが作成できているところからの作成手順です。

## Bean classの作成

SessionBeanのclassを作成します。

- 右クリック > New > Class で選択
- Package: pdprof.jsf
- Name : HelloBean 
- Finish ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/8ab4f283-50ee-4981-804a-41925f1e4fa4.png)

- classのアノテーションを追加
- message filed の追加
- Validation size の追加
- setter/getter メソッドの作成

```HelloBean.java
package pdprof.jsf;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.validation.constraints.Size;

@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {
	
	@Size(min=3)
	private String message = "Hello World!";
		
	public String getMessage() {
		System.out.println("HelloBean.gettMessage : << " + message);
		return message;
	}

	public void setMessage(String message) {
		System.out.println("HelloBean.setMessage : >> " + message);
		this.message = message;
	}

}

```

## XHTMLの作成

XHTMLを新規に作成します。
- 右クリック > New > HTML File

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/631e9af8-44f0-4131-b8e5-8810a2f5a33b.png)


- File Name : index.xhtml
- Next ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/3670c001-a09d-423f-943b-b2337678e829.png)

- New Facelet Composition Page を選択
- Finishをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/2ce1f949-00c4-45e1-bd26-73dca085011d.png)


多少は流用しつつbodyのところを変更する。
```index.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:f="http://xmlns.jcp.org/jsf/core">

<body>
helloBean.message : <br />
#{helloBean.message}<br />
<hr />
<h:form>
Input Message (3 characters minimum): <br />
<h:inputText id="message" value="#{helloBean.message}" /><br />
<h:commandButton id="button" value="Send" action="index.xhtml" />
</h:form>
</body>
</html>
```

## web.xml の作成（更新）

Webプロジェクト作成時にweb.xmlを作成していない場合には作成をして、更新をします。
作成方法は

- 右クリック > Java EE Tools > Generate Deployment Descriptor Stub 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/7220901a-7619-4afe-b10d-3ae18d0e26f3.png)

で web.xml が作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/375e5d95-8e02-4ea3-8e22-c30c15c33119.png)


これに、Faces Servlet の servletとservlet-mappingを追加します。また welcome-file に index.xhtml も追加します。

```web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.1"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
	<display-name>jsf</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.jsp</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>index.xhtml</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
</web-app>
```

# Libertyテスト環境

今回は tWAS でも動作するように、Java8, jsf-2.2, beanvalidation-1.1 で動かします。
server 構成は以下になります。

```server.xml
<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>jsf-2.2</feature>
		<feature>beanValidation-1.1</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

    <!-- Default SSL configuration enables trust for default certificates from the Java runtime --> 
    <ssl id="defaultSSLConfig" trustDefaultCerts="true"/>

    <applicationMonitor updateTrigger="mbean"/>

    <webApplication id="jsf" location="jsf.war" name="jsf"/>
</server>
```


# Libertyテスト環境の自動構築

これまでの方法で既存環境に構成は可能ですが、環境をdockerで用意する方法です。

用意したGitレポジトリをクローンします。
```
git clone http://github.com/pdprof/jsf.git
cd jsf/jsf-docker
```

Libertyのイメージをビルドして開始します。
```
./setup-docker.sh
./start.sh
```

Libertyの起動を確認します。JSF にアクセスします。

http://localhost:9080/jsf


# index.xhtml で入力

アクセスしたindex.xhtmlでJSFをテストします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/4ed25bcb-19ed-4a53-b56d-6d43bf99d79b.png)

Input Message に入力して、Send ボタンをクリックするとページが更新されます。
Helloと入力してSendした場合は

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/24ec1366-d939-4d4c-8c93-ba3a299f9bcb.png)


```messages.log
[3/30/25, 13:59:53:126 UTC] 00000053 SystemOut O HelloBean.setMessage : >> Hello
[3/30/25, 13:59:53:129 UTC] 00000053 SystemOut O HelloBean.gettMessage : << Hello
[3/30/25, 13:59:53:130 UTC] 00000053 SystemOut O HelloBean.gettMessage : << Hello
```

のように HelloBeanのsetter/getter が動作しているのがログから分かります。




指定したSizeのValidationは2文字の Hi では

```messages.log
[3/30/25, 14:02:40:023 UTC] 0000003f org.apache.myfaces.lifecycle.RenderResponseExecutor W There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are: 
- j_id_3:message: size must be between 3 and 2147483647
```

とログ出力されて、setter/getter の動作は確認できません。

このValdationは MyFaces Bean Validation support enabled のメッセージで使えるか確認できます。

```
[3/30/25, 13:57:15:735 UTC] 00000042 org.apache.myfaces.util.ExternalSpecifications 
     I MyFaces Bean Validation support enabled
```



# トラブルシューティング

毎度のことですが、よくつかう dockerコマンドを書いておきます。この文書でもpodman, dockerとまとまりがないですが、Linux では dockerがpodmanを呼び出すようになっていました。

```
docker ps # 動作中のContainer確認
docker logs -f jsf # ログ確認
docker restart jsf # 再起動
docker inspect jsf # container 確認
docker exec -it jsf bash # Container内状況確認
```

# まとめ

Libertyの環境を構築して、JSFをテストしました。


# 参考

以下ページを参考にさせていただきました。ありがとうございます。

https://qiita.com/nifram/items/123ec5689da654b365aa