Kohei Nozaki's blog 

ProjectStageをJNDIで設定する


Posted on Tuesday Jan 21, 2014 at 07:39AM in Technology


環境

  • WildFly 8.0.0CR1

何をするの?

JSFのProjectStageをJNDIから取得するように設定してみます。このProjectStageというのはJSFエンジンに与えるパラメータの一種で、値としてはPRODUCTION(本番稼働フェーズ)、DEVELOPMENT(開発フェーズ)などが定義されています。開発フェーズではDEVELOPMENTにしておくと、問題発生時にデバッグのための情報が多く吐き出されたり、本番稼働フェーズではPRODUCTIONにしておくと、パフォーマンスが向上したりします。

基本的にはweb.xmlに定義するのですが、web.xmlに直接書いてしまうと本番稼働時にPRODUCTIONに変更したい、となったときに若干面倒です。そこでこの値をJNDIから取得するようにしてみます。

JNDIの設定

jboss-cliを起動

wildflyのbinディレクトリ内に存在するCLIの管理コンソールです。GlassFishのasadminに相当すると思われます。Windowsではjboss-cli.bat、Unix系ではjboss-cli.shを使って起動します。起動するとこんな感じになります

$ ./jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] 

接続

connect とコマンドを打つとAPサーバに接続するようです

[disconnected /] connect
[standalone@localhost:9990 /] 

JNDIエントリを新規作成

新たにJNDIエントリを追加するときはこれ。java:/env/jsf/ProjectStageがキー、Developmentが値になります

/subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:add(binding-type=simple,value=Development,class=java.lang.String)

こういう感じにsuccessと出ればOK

[standalone@localhost:9990 /] /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:add(binding-type=simple,value=Development,class=java.lang.String)
{"outcome" => "success"}
[standalone@localhost:9990 /]

JNDIエントリを更新

既に作ったエントリを更新する場合はこんな感じ。java:/env/jsf/ProjectStageをUnitTestに変更する例はこちら

/subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:write-attribute(name=value,value=UnitTest)

JNDIエントリを確認

こんな感じ。一番右側のvalueというところに設定した値が出ています

[standalone@localhost:9990 /] ls /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage
binding-type=simple     cache=undefined         class=java.lang.String  environment=undefined   lookup=undefined        module=undefined        type=undefined          value=UnitTest          
[standalone@localhost:9990 /] 

JNDIエントリの一覧

[standalone@localhost:9990 /] ls /subsystem=naming/binding
java:/env/jsf/ProjectStage  
[standalone@localhost:9990 /] 

まだ1つだけしか無いようですね

JNDIエントリを参照するJSFアプリを作ってみる

プロジェクトを作る

ここまでに述べた通りJNDIエントリは作成してあるものとします。ここに書いたのと同じ要領で空っぽのJavaEE7プロジェクトを作ります。プロジェクトの設定でCDIを有効にしておきます。これをやると空のbeans.xmlが作成されます。

web.xmlを作る

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<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>
	<resource-ref>
		<res-ref-name>jsf/ProjectStage</res-ref-name>
		<res-type>java.lang.String</res-type>
	</resource-ref>
</web-app>

jboss-web.xmlを作る

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
	<resource-ref>
		<res-ref-name>jsf/ProjectStage</res-ref-name>
		<res-type>java.lang.String</res-type>
		<jndi-name>java:/env/jsf/ProjectStage</jndi-name>
	</resource-ref>
</jboss-web>

CDI管理Beanを作る

package psjndi;

import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;

@Named
@RequestScoped
public class TestBean {

	public String getProjectStage() {
		return FacesContext.getCurrentInstance().getApplication().getProjectStage().toString();
	}
}

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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head></h:head> 
<body> 
#{testBean.projectStage}
</body> 
</html>

資源の配置場所を確認

上記の資源たちの配置はこんな感じになります。beans.xmlも存在する事を確認してください。

確認したらデプロイしてみます。

アクセスしてみる

JNDIに設定した通りDevelopmentと表示されます。

ProjectStageを変更してみる

jboss-cliから変更してみる

UnitTestに変更してみます。

[standalone@localhost:9990 /] /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:write-attribute(name=value,value=UnitTest)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
[standalone@localhost:9990 /] 

アプリにアクセスしてみる

これだけやってブラウザをリロードしてもDevelopmentのままです。まあoperation-requires-reloadとか言っているので再起動なりの作業が必要なのでしょう。そこで再起動かけてみます。Servers窓からWildFlyの右クリックメニューを表示してRestartを選びます。再起動したら再度リロードしてみます。 アプリの資源を一切触る事無く変更することができました。

ProjectStage一覧

  1. Development
  2. UnitTest
  3. SystemTest
  4. Production

Productionに近づくほど例外とかの詳細度が低くなっていきパフォーマンスが向上するらしい。うろ覚えですが、速くなる他にも、キャッシュとかの挙動が変わったりJSFが自動で用意するJavaScriptが差し替えられていたりしたような記憶が有ります。おそらくDevelopmentではデバッグしやすいJavaScriptが送られたりするのでしょう。

参考文献



No one has commented yet.

Leave a Comment

HTML Syntax: NOT allowed