Scalatra w/ IntelliJ IDEAでのデバック設定
ScalatraをIntelliJで触り始めました。
デバックするのに少しはまってしまったのでその時のメモ。
Scalatraのプロジェクトを作るのは、本家サイトにあるように必要なツール類をインストールし、
>g8 scalatra/scalatra-sbt
を実行すれば簡単に作れます。
Installation | Scalatra
IntelliJ IDEAを使う場合もplugins.sbtに
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")
を追加して、sbt実行後
>gen-idea
を叩けばIntelliJでプロジェクトを開けるようになります。
この後、ここにあるようにすれば大丈夫かと思ったら
IDE Support | Scalatra
こんなエラーが出てポート5005で起動できませんでした。
※ちょっと調べるとWindowsだからっぽいんのですが原因は不明
How To Debug With Typesafe Activator Play Framework Using Eclipse » Andika Nugraha
このページを参考に、
set "JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
でコマンドプロンプト上でJAVAの実行環境を設定してあげると、sbt実行で
Listening for transport dt_socket at address: 5005
と5005でListenしてくれるようになります。
この後はIDEの設定で、Remoteの実行設定をしてあげれば、実行後
Connected to the target VM, address: 'localhost:5005', transport: 'socket'
と表示され5005ポートへの接続が確立しました。
これで無事IDE上でのデバックが可能となりました。
参考にしたサイトはPlayとEclipseという内容でしたが、特にIDEとフレームワークの違いはなく
SBTを使っていたら同じ対応でできるはずです。
クロージャーについて
2/8にScala関西ビギナーズという勉強会でLTをしてきました。
資料はこちらなのですが、
LTではこういった関数
def outer(x:Int) = { var more = x (y:Int) => y + more }
を定義し、P.15でクロージャーとは
「 引数で渡された変数以外の変数をさわれる関数のこと(ただしスコープ内の) 」という事で、「outerを実行すると(y+more)を実行する関数オブジェクトを取得。このオブジェクトがクロージャー」と説明しました。
ただ、だと「スコープ内外って?」という疑問もわきますし説明が不十分だったのと、いまいち自分の理解も怪しかったので、もう少しクロージャーについて調べてみました。
クロージャ - Wikipedia
Wikipediaの概要の説明をここで言いたいことに纏めるとこんな感じです。
「外側の関数の変数を参照するのがクロージャーで、クロージャーは外側の関数の実行時に生成される。クロージャーは外側の関数のスコープにある変数を全て参照できる。クロージャーはその変数を束縛する。」
なので上述の「ただしスコープ内の」というのは詳細には「外側の関数のスコープ内の」といえるかと思います。
クロージャーが変数を束縛している様子は英語版のクロージャーのページの例がわかりやすかったのでscalaで書きなおしてみました。
counterを実行すると、int型のyを受け取り外側の関数の変数xに足して画面にxを表示するクロージャーを返します。
counter1_incrementとcounter2_incrementの2つのクロージャーを生成します。
それぞれの動作は相互に影響することなく処理していることがわかります。
またcounter1_increment、counter2_incrementの処理をした後にcounter3_incrementを生成し実行しても、それまでの
counter1_incrementの結果に影響されていることはありません。
つまり外側の関数の変数xを取り込んでいるって事ですかね?
「変数xを束縛している」という事で、このような性質をもった関数オブジェクトの事をクロージャーという事になるんだということなんですね。
jcp(java community process)とかjava.netとかの話
JavaEE7のJSF2.2で追加された機能を調べるのに「やっぱり一次資料じゃないと!」と思い、Javaの一次資料であるJSRを見てみたのでそのときのメモ。
Javaの仕様はJSRという形で仕様が策定され、各仕様ごとに番号が振られています。
今回調べようとしているJSF2.2は344が振られてJCPにその仕様が正式な資料として公開されています。
確かにJCPの中を探していけば仕様書はあるのですが、結構わかりづらくしかも英語ですので骨が折れます。
また、「Javaは仕様がオープンで、策定プロセスもオープンなのでみなさんぜひ参加しましょう」とか言われてもどこをどうしていけば参加できるかも、初心者にはわかりづらい印象です。
まず目的のJSRまでたどり着くには、トップ画面の左側にある「JSRs」と書かれたあたりから始めます。
とりあえず、「List of All JSRs」をクリックするとすべてのJSRの一覧が表示されます。
今回の目的のJSR-344は画面下の方に行くとあります。
ここでは以下の情報がわかります。
-
-
- -
-
This JSR is an update to the 2.1 version of the JavaServer Faces specification. This is the first major revision of the JavaServer Specification since JSR 314.
-
-
- -
-
このJSRはJavaServer Facesの2.1の仕様からのアップデートです。これはJSR314からの最初のメジャーリビジョンです。
-
-
- -
-
とあり、目的のJSRである事がわかります。
また、Latest StageがFinal Releaseという事で最終版という事、Spec LeadがOracleのEdward Burnsという方である事がわかります。
この人ですね。edburns's blog | Java.net
このまま「Download Page」をクリックし詳細のページを表示します。
詳細のページに「Specification」(仕様)の項目のDownloadから、今回の最終的な目的であるJSF2.2の仕様書がゲットできます。
そのほか、Reference実装のダウンロード(Reference Implementation)やメーリングリスト(JSF Mailing Lists)、不具合(Issue List for JSR 344)、変更履歴(Change Log for JSF 344)情報などもあり、仕様策定のプロセスをリアルにウォッチ、もしくは意見したくなった場合はこれらのメーリングリストへ投稿すればいいって事ですね、多分。
最後にメーリングリストのページを見てみますと4種類のメールが載ってますが(commit, issue, jsr344-experts, users)、意外と購読者(subscribers)が少なく(commitで12、issue40とか)、メッセージの数もcommitで318、issueで7804と思っていたほど多くありませんでした。
もっと世界中の多くのエンジニアが喧々諤々しているのかと思っていましたが、これなら結構敷居が低いのかな、と思いました。
次はここでダウンロードしたJSF2.2の2.1からの変更点についてまとめてみようかと思います。
JSFについてもう少し調べてみました。
先週やったJJUCの一人ハンズオンでJSFを触ったので、もう少し調べてみたので自分用にメモ。
JavaEE7のJSFは2.2で、JavaEE6のJSF2.0からは機能追加という位置づけらしく2.0を知っていたら2.2もキャッチアップ簡単、ということらしいので2.0から理解してみました。
まず、最初にプロジェクトの作成です。Mavenで作成するので「Maven」の「Webアプリケーション」を選択します。GlassFish3.1.1、JavaEE6で作成です。
作成後はプロジェクトのプロパティ(プロジェクトを選択し右クリック)から「フレームワーク」で「JavaServer Faces」を追加します。「ライブラリ」「構成」「コンポーネント」はデフォルトのままです。
以下のweb.xmlがWEB-INFフォルダに作成されます。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> </web-app>
JSF2系からは画面はjspではなくfaceletsで作るのがセオリーだそうで、フレームワーク追加時に新しく作成されたindex.xhtmlを使います。もともとあったindex.jspは不要なので削除します。
この時点でももうプロジェクトは実行可能です。
今回はここからtwitterもどきのアプリを作っていこうと思います。
EJB・JPAなどの連携はなしで、画面側の処理だけ実装してみようと思います。
まず画面と連携してデータを処理する管理ビーン(ManagedBean)を作成します。
POJOからでも作成可能ですがプロジェクトの右クリックでJSF管理対象Beanを選択し任意のクラスを作成します。
これが自動生成されたクラスで、ManagedBeanは引数なしのコンストラクタが必要です。
@ManagedBean @RequestScoped public class TwitterMgdBean { /** * Creates a new instance of TwitterMgdBean */ public TwitterMgdBean() { } }
ここから画面(xhtmlファイル)から渡されるプロパティを定義していきます。
ここでは、画面から渡されるつぶやき情報のtweetsはメモリ上に保持するようにしています。
@ManagedBean @RequestScoped public class TwitterMgdBean { /** * 過去のつぶやき */ private static final List<String> tweets = new ArrayList<String>(); /** * つぶやき */ private String tweet; /** * Creates a new instance of TwitterMgdBean */ public TwitterMgdBean() { } public String getTweet() { return tweet; } public void setTweet(String tweet) { this.tweet = tweet; } public List<String> getTweets() { return this.tweets; } }
次はxhtml側の実装です。ハンズオンの時と同じように
感じでManagedBeanと連携するプロパティを記載します。
<?xml version='1.0' encoding='UTF-8' ?> <!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:c="http://java.sun.com/jsp/jstl/core"> <h:head> <title>つぶやき</title> </h:head> <h:body> <h:form> <h:outputLabel value="つぶやき"/><br /> <h:inputTextarea value="#{twitterMgdBean.tweet}"></h:inputTextarea><br /> <h:commandButton value="つぶやく" action="#{twitterMgdBean.doTweet()}"/> </h:form> <hr/> <h1>過去のつぶやき</h1> <c:forEach var="t" items="#{twitterMgdBean.tweets()}"> <div style="background-color: #9999ff; margin: 10px; padding: 5px;"> <h:outputText value="#{t}"></h:outputText> </div> </c:forEach> </h:body> </html>
これだけで一応、画面とサーバ側で連携する実装は完了しました。
つぶやきを入力しつぶやきボタンを押下すると画面に順に表示されていきます。
ただこれだけでは普通のアプリとも言えないので普通は実装されるであろうバリデーション処理を実装してみます。
単純なバリデートだとアノテーションを使って簡単に定義・実装可能です。
アノテーション@Sizeと条件をプロパティに設定するだけです。
@ManagedBean @RequestScoped public class TwitterMgdBean { /** * 過去のつぶやき */ private static final List<String> tweets = new ArrayList<String>(); /** * つぶやき */ @Size(min = 0, max = 140, message = "140文字以内で入力してください") private String tweet;
画面側にもエラー時に表示するタグ
必須設定もrequred="true"の追加だけで設定可能です。
<h:inputTextarea id="tweet" value="#{twitterMgdBean.tweet}" required="true" requiredMessage="必須です"></h:inputTextarea><br />
複雑な条件が必要な場合はカスタムバリデータを実装しバリデートさせることもできます。
カスタムバリデータはjavax.faces.validator.Validatorを実装する必要があり、今までJavaをやってきた人間であれば、特に迷うことなく実装可能かと思います。
ここでは、ツイッターとは関係ないですが郵便番号のバリデーション処理を実装してみます。
不正な値の場合ValidatorExceptionをスローする仕様です。
@FacesValidator(value = "postalCodeValidator") public class PostalCodeValidator implements Validator { @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String v = (String)value; Pattern p = Pattern.compile("[0-9]{3}-[0-9]{4}"); Matcher m = p.matcher(v); if (!m.matches()) { throw new ValidatorException(new FacesMessage("郵便番号形式ではありません")); } } }
ここの@FacesValidator(value = "postalCodeValidator")のvalueをxhtmlで指定し画面項目への設定を行います。
<div><h:message for="postalCode"/></div> <h:outputLabel for="postalCode" value="郵便番号"/> <h:inputText id="postalCode" value="#{twitterMgdBean.postalCode}" required="true" requiredMessage="必須です" validator="postalCodeValidator"></h:inputText><br />
このように不正な郵便番号を入力するとエラーメッセージが表示されます。
ここまでJSFを実装してみましたが、ハンズオンの時と同じように簡単にアプリの実装ができました。
特にここまでサードパーティ製ライブラリを追加することなく実装できるので楽ですね。
この次はJavaEE7のJSF2.2について勉強してみようと思います。
今回もソースかgithubにアップしています。
https://github.com/amkt922/jsf-sample
JJUC CCC 2013 Fallのハンズオンをしてみました。
JJUC CCC 2013 Fallに参加できなかったので、そこで実施された「R5-1 Java EEハンズオン」を一人ハンズオンをしたのでメモ。
資料が大変わかりやすく書かれていたので、特に詰まることなくJavaEE7+WebSocketアプリを作れました。
資料はこちら
Java EE 7 HoL on JJUG CCC | 寺田 佳央 - Yoshio Terada
ただ一点、GlassFishハンドルのNetBeans7.4をダウンロードしたのですが、GlassFish4が認識されずもともと入っていた3.1.2.2しか使えなかったので新たにインストールする必要がありました。
「ツール(T)」→「サーバー(S)」を選択しこの画面からサーバを追加。
5章まで終わるとひと通り動くものができたので、クラスタリング構築部分は飛ばして、chat機能を追加してみました。
追加した内容は
- chat用のManagedBeanを追加
- chat用のJSFページを追加
しかもMBeanはIndexPageMgdBeanと同じ(@Namedのvalueは変更)、JSFページはclient-endpoint.htmlとadmin/index.xhtmlを合わせてメッセージ送信部分をajax処理に変えただけです。
MBeanのChatPageMgdBeanクラス
@Named(value = "chatManage") @RequestScoped public class ChatPageMgdBean {
<h:body> <h2>WebSocket RealTime Information Transfer2</h2> サーバ接続ポート:<input id="server-port" type="text" value=""/> <input id="connect" type="button" value="Connect" onclick="connectServerEndpoint();"/> <input id="close" type="button" value="DisConnect" onclick="closeServerEndpoint();"/> <br /> <h:form> <h:inputText id="textField" value="#{chatManage.message}" /> <f:ajax execute="textField"> <h:commandButton value="sendMessage" action="#{chatManage.pushSendButton()}" /> </f:ajax> </h:form> <table border="1" id="TBL"> </table> </h:body>
ハンズオンのプロジェクトにこれだけ追加したら簡単なchatアプリですが完成しました。
それぞれlocalhost:8080に接続しメッセージを送付すると両方のブラウザに即座にメッセージが表示されます。
<f:ajax />
を追加するだけというところです。
ほんとにJavaEE7+JSFを使うと業務系のアプリだと簡単に構築できそうです。
ソースはgithubにアップしています。
https://github.com/amkt922/WebSocket-HoL
PlayFramework関西ビギナーズ 第2回でLTしてきました
人生初のLTを8/3(土)のPlayFramework関西ビギナーズでやってきました。
思ってたほどは緊張しませんでしたが5分持ちませんでした。。。多分4分位。
こんな機会を今後はもっと持っていければと思っています。
大した内容ではないですが、発表したスライドはこちら。
※名前のあたりを若干加工しました。
勉強会自体は、全体的にORMの話題が多く
Slick vs Squerly vs scalikejdbc
という感じで、結局Anornより良いよねってことらしいので、
今度自分が触るときは、このあたりのORMを触ってみようかと思います。
やっぱり「Scala力がそもそも全然ないよね」ってことを痛感した勉強会でした。
まあ、コップ本をちょっと読んだだけなので当たり前ですが、
Javaを知っていたらScalaもわかるよ
ってのはホントか?って思ってしまいます。
Scalaを知れば知るほど、Javaとの違いばかりが目につき、
Scala意味不明
ってなってます。
ちょっとづつでもScala、Play力をつけていけたらとおもいます。
組み込み制御構造について
Scalaでは組み込みの制御構造は、コップ本によるとわずかのようです。
if、while、for、try、match、関数呼び出しだけある。
そのうち、while以外はif式、for式などHoge式と呼ばれるのに対し、
whileだけwhileループと呼ばれ式に分類されていません。
今回はそのわずかな制御構造のうち、if式とwhileループについて書こうかと思います。
- if式
Scalaではifも値を返すので、以下のように簡単に処理が記述でき、var変数を使わないですむようになっています。
def isOdd(a: Int): Boolean = if (a % 2 == 1) true else false
この場合、boolean値を返してます。
- whileループ
whileループはコップ本には「whileループは値を返さないので、」と書かれ、
なるべく使わないように言われており、whileやdo-whileがコードにあれば、「疑いの目を向けてみるべきだ」
とまでの言われようです。
手続き型言語で従来whileを使っていた個所は、再帰によりwhile同等の処理をすることが
関数型らしい実装の仕方のようです。
次はfor,match式について勉強したいと思います。