業務システムエンジニアのためのHTML5勉強会#04 Web✕Java - HTML5で進化したWeb標準を、Java技術でどう扱うのか? -

業務システムエンジニアのためのHTML5勉強会#04 Web✕Java - HTML5で進化したWeb標準を、Java技術でどう扱うのか? - に行ってきました。

HTML5の話はあまりなくて、JJUG的な勉強会でしたがw、気になってたけど手を出してない技術の話をいっぱい聞くことが出来ました。
Tomcat、Struts、Seaser、Springあたりはもう時代遅れ的な話がちらほらあって、いろいろ変わってるんだなぁとか思ったり。

Java EE の概要と HTML 5 の取り組み

日本オラクル シニアJavaエバンジェリスト 寺田佳央 さん

Tomcat、Strutsやめよう運動をしてる。

Struts1.xはサポート終わる。
世界のトレンドではStruts1.x、2.x共に選ぶ人が減っている。

Struts、Spring、Hibernateはすべて作ってるところが違う。
システム納品後の瑕疵担保期間はいいが、それが終わったら誰が見るのか。
セキュリティアップデート等でどれかがバージョンアップしたら他との相性はだれが保障するのか。
ほとんどのエンドユーザはそんなことは理解しないで使っており、結果的に大きな保障問題に発展することがある。

Java EE6では必要なものがオールインワンですでに入っている。
脆弱性はパッチを当てればOK。
⇒独自技術から標準技術への移行

JavaEE7はJavaEE6と比べて注目度がとても高い。
ローンチ・イベントに世界から1万人超が参加。

Java EE6までは、アプリ内でスレッドを作るのが禁止されていた。
スレッドがアプリサーバーとは違う環境で動くようになっており、例えばWebアプリを停止してもスレッドが動き続けるので危険。
JavaEE7からは安全にスレッドが使用できるようになった。

Strutsから移行する人のためのJSF基礎

グロースエクスパートナーズ株式会社/JJUG幹事 久保 智 さん

JSFとは
2004にv1.0がリリース
Strutsの開発者が使用策定にかかわっている。

Ajax前提に作られているので、リッチなUIを作りやすい。
Strutsに骨子が似ているため、理解しやすい。

JavaScriptレスなAjaxを使用したUIが作成可能。
JSFはIE8ぐらいから動くが、プラグインを使用すると最新のブラウザでないと動かないことがあるので注意。

JSFの1.xと2.xは別物
1.x使うくらいならStrutsの方がまし。

managed-bean

StrutsではActionFormとActionで分かれていた入力値処理を1つに纏めた。
XMLによる設定ではなくアノテーションで指定。

XML+タグライブラリ

JSPと違い、Servletに変換されなくなった。
エラー時のスタックトレースにXHTMLの行数で表示される。

JSF Validator + Bean Validator

JSF Validator:バリデーションを画面に直接書く
Bean Validator:プロパティファイルに書く。アノテーションベースのエラーチェック

JavaプログラマのためのScalaプログラミング

ストーンシステム 代表 石黒尚久 さん

ScalaとJavaの違い

  • 文末のセミコロンは不要
  • publicはデフォルトなので不要。(予約語ですらない)
  • System.out. がデフォルトインポート済みなので不要
  • returnは書かない
  • getter/setterは不要。自動で作成される。
  • 変数定義が違う
    var data: int = 0 // 型が後にくる
    var data2 = 100 // int型がわかっているので省略可能
  • メソッドの書き方が違う
    表記上の省略がいくつかあるので、同じ定義でも書き方が何種類かある。
  • 引数にデフォルト値の指定が可能
  • ScalaはJavaよりも純粋なオブジェクト指向。プリミティブ型もオブジェクト

他にもいろいろ
Javaの冗長な記述を無くそうとしているのではないか。

石黒さんの書かれた本

速攻理解!JavaプログラマのためのScalaプログラミング

速攻理解!JavaプログラマのためのScalaプログラミング

JavaからScalaへ ~ScalaでWeb開発はこう変わる~

NTTデータ先端技術 竹添直樹 さん

Javaで生産性上げるのに限界を感じてScalaに取り組み始めた。

Javaアプリを移行したらコード量が40~50%削減。想像以上に減った。
スクリプト言語のようなFlexibilityとJavaのようなSafetyが特徴。

業務でも十分に使える言語

Play2

一番メジャーなフレームワーク

タイプセーフでWebSocketも簡単に使える。

ステートレスでサーバーサイドで値を持たない。セッションIDだけCookieに渡してデータはKVSとかに置いたり、クライアント側で管理したりする。
warにするプラグインがあるが、茨の道なのでやめたほうがいい。
ステートレスなので、既存システムをもってくるのには向いていない。

竹添さんの書かれた本

Scala逆引きレシピ (PROGRAMMER’S RECiPE)

Scala逆引きレシピ (PROGRAMMER’S RECiPE)

新宿鮫:第16回AWSもくもく勉強会 EclipseからElasticBeanstalkのTomcatへデプロイ

新宿鮫:第16回AWSもくもく勉強会に参加しました。

今回はElasticBeanstalkを使って、EclipseからTomcatへデプロイしてみます。

AWS SDKの入ったEclipseの新規作成から AWS Java Web Project を選択

f:id:yuji0316:20130828204949p:plain

プロジェクト名は MokuMokuBeanstalk で。

f:id:yuji0316:20130828204950p:plain

プロジェクトができたら、右クリックして [Amazon Web サービス]-[Deploy to AWS Elastic Beanstalk...]

f:id:yuji0316:20130828204951p:plain

今回は 手動で新規サーバーを定義 を選択します。

f:id:yuji0316:20130828204952p:plain

なんかアプリケーション名と環境名を入れろと言われたので、適当に入力

f:id:yuji0316:20130828204953p:plain

追加情報は特になにも指定しません。
Beanstalkでは新たにEC2が作成されるので、ログインする必要あれば Key pair を指定しておく感じでしょうか。

f:id:yuji0316:20130828204954p:plain

リソースは既にMokuMokuBeanstalkが追加されていたのでそのまま完了ボタンを押下。
aws_web_testは昔ちょっといじったときのやつなので無視して下さいw

f:id:yuji0316:20130828204955p:plain

ぬーるーぽー!

f:id:yuji0316:20130828204956p:plain

実は昔いろいろ試したんですが、どうやら手動でサーバーを作るとこれが出るらしいです。
ただ、その時一緒にやっていた人はすんなりとできていたので、う~んなんででしょw
EclipseにSDK入れたのも結構前なので、最新版が出ていれば動くかもしれませんが、今回はパスでw
そのうちリベンジします。


気を取り直して、Management ConsoleからBeanstalkのサーバーをあらかじめ作成しておきます。

Tomcatサーバーを選択

f:id:yuji0316:20130828204957p:plain

頑張っていろいろ起動し初めて、3分程待つと完了します。

f:id:yuji0316:20130828204958p:plain

さて、Eclipseに戻りましょうw

さっき手動を選んだところを「既存のサーバーを選択」にします。

f:id:yuji0316:20130828204959p:plain

ここはさっきと同じで完了。

f:id:yuji0316:20130828205000p:plain

Eclipseのビューで何かの処理が開始します。

f:id:yuji0316:20130828205001p:plain

順番が前後しましたが、事前にJSPを↓のように書き換えてあります。

f:id:yuji0316:20130828205002p:plain

そして、起動が終わったら自動的にEclipse内にブラウザのタブが表れて、画面が表示されました。

f:id:yuji0316:20130828205003p:plain

もちろんChromeからも見られました。

f:id:yuji0316:20130828205004p:plain

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

第41回 HTML5とか勉強会 事例に学ぶHTML5開発

第41回 HTML5とか勉強会 事例に学ぶHTML5開発に行ってきました。

Inside wri.pe

増井雄一郎さん(@masuidrive)(FrogApps)

wri.peというサイトについての話。

今年のGWに家にこもって作った。基本機能は2日で。

1人でやるので、運用はしない、バックアップは自動で。
→ Herokuで。毎月$200かかっているが。。。

とりあえず作ってつぶやいたら、200人登録があった。
本格的に作ることにしたので、個人だからhogehogeとかはいやだ。

デザインはDribbleとかで。

テストはCapybaraとか使ってる。
テスト作るのは2週間かかってる。

Evernoteとの連携機能のリクエストが多かったので作った。
まだ正式リリースはしていないが、トップページでコナミコマンドを打つと使えるw
コナミコマンドを認識するkonami.jsというのがあるので使ってみたかったw

Inside "お台場合衆国 リアルスコープブースサイネージ"

比留間 和也さん(@edo_m18)(カヤック)

Chromeで作成。42インチの縦長画面。
画面が大きいので、普通のWebと同じで作っていたら違和感があったためデザインをほぼ作り直した。

WebGL

背景はWebGL
Mayaで作ったものをInka3Dでエクスポート。
OSを巻き込んで落ちることがあった。
http://goo.gl/i0t7naで見ることができる。

カメラ撮影

カメラ使用許可の確認が出てしまうので、getuserMediaで取得したストリームを保持し続ける。
httpsで接続すると、リロードしてもセッションを保持し続けてくれた。httpだと毎回確認が必要

動画

動画の再生がなぜか停止することがあった。強制的にload/playをして再実行。
なかなか出ないレアケース
JavaScriptからは正常に再生しているように見える。
いろいろ調べたが、結局原因はわからなかった。

Video、Canvas要素にはCSS Shaderが適用されない。

8時間耐久実行

  • メモリ管理を徹底。
  • 隠しコマンドで管理画面を用意
  • 耐久テスト 朝起動して帰るまで再生しっぱなし
  • 実機テスト

その他

現場で起きた不具合をその場で修正→反映が迅速に行えた。
遠隔で更新作業を行い、現場担当者で反映することができるように。

Inside World Wide Maze

Saqooshaさん @Saqoosha(Katamari Inc)

スライドはこちら

Webサイトを立体迷路にするWorld Wide Mazeの紹介。

使っている主な機能

  • WebGL(three.js)
  • Web Workers(ammo.js, Physijs) 主にボールの動きの物理演算
  • WebSocket(Socket.id)
  • DeviceOrientation

作成に6か月。通常キャンペーンサイトは2か月。

スマホの傾きをリアルタイムにPCに送信するには

傾き情報を取得

DeviceOrientation イベントを使って傾き情報を取得。
呼び出される間隔
iOS + Safari : 100ms
Android4 + Chrome : 200ms

傾きの取れ方が、端末やブラウザによって違う。
W3Cの規格通りになっていないものが多い。

WebSocketでPCに送る

スマホからPCに直には送れないので、間にサーバーが必要。
サーバーはNode.js & Socket.io

PCとモバイルのペアリング。
PCとランダムな番号のペアをサーバーで覚えておいて、スマホからその番号を指定。

レイテンシー
ローカル:~5ms
日本のサーバー:~30ms
USのサーバー:~200ms

http://saqoo.sh:13000/で、スマホの傾きをPCで確認できるデモ。
PC画面の上にある数値をスマホに入力。

サーバーを経由せずにスマホからPCに送る方法が最近出てきた。
WebRTC
ペアリングをするサーバーはやっぱ必要。

Inside マンガテレビ

小松健作さん(@komasshu)(NTT Communications)

スライドはこちら
記事はこちら

動画をリアルタイムにマンガ風にするマンガテレビの話。

  1. getUserMediaでビデオ取得
  2. CanvasPixelArray取得
  3. フィルタ処理(参考)

WebSpeechAPIで音声認識
W3Cでドラフトにもなっていない。Chromeのみ実装
httpsじゃないとしょっちゅう確認ダイアログがでる。

Headtrackr.js
顔検出ライブラリ
Face.jsより高速で動く (MBPで30fpsぐらい)
最初認識するまでは遅いが、その後は早い。
1人しか認識できない。

フィルター処理は毎回30万ループ位する。
目標は60fpsで。 テストはChromeのツールのProfileがかなり便利。

パフォーマンスチューニングのポイント

  • 関数呼び出しは減らそう
  • プロパティ参照は無くそう
  • 演算処理はなるべく減らそう
  • ビットシフトは、若干早くなる
    (でも、なんか頭が良くなった気がする)
  • 文字を数値化する場合parseIntの方が早い(特にChrome)
    parseInt(“1”) < “1”|0
    InternetExplorerを除く

HTML5×Internet Explorer ~IEを使ってどこまでモダンなWebへ突き進めるのか?~

業務システムエンジニアのためのHTML5勉強会#03 HTML5×Internet Explorer ~IEを使ってどこまでモダンなWebへ突き進めるのか?~に行ってきました。

最初のセッションは互換性のための実用的な対策、次はMSの人も感心していたくらい超マニアックな内容、最後はMSの人によるIE11の最新情報と、とにかく濃かったですw

CodeIQさんからどらやき頂きました。

f:id:yuji0316:20130801190309j:plain

いいね!を10,000件集めると会社で言ってしまったそうです。あと少しなので、いいね!しましょうw

新しいIEとJavaScriptで動かす最近のWebアプリケーション

ピクセルグリッド 小山田さん(@yomotsu)

新しいIEでこれまでのものが動かないときどうするか。

いろんなサイトで未対応となっている原因として

  • Quirks Mode(後方互換モード)で実装している
  • IE独自拡張を使っている
  • プラグインを使っている
  • 保証できないから未対応にしている

Quirks Modeで実装している

Standard ModeとQuirks ModeでCSSの解釈が異なるためデザインが崩れる。
DOCTYPEでどちらを使うか選べる。
これから使うものはStandard Modeにしておいた方がいい。

IE独自拡張を使っている

昔はブラウザでできないからプラグインがいろいろと存在していたが、今は標準技術になっているのでそれを使う。

  • ActiveXObject -> JavaScript
  • VBScript -> JavaScript
  • DataBinding -> Data属性
  • VMS -> SVG

プラグインを使っている

古いIEのモードで動くように設定する。
方法はいろいろあるが、metaタグで指定するのが簡単。
古いIEをほぼ再現できる。

これからのWebシステム構築

IE7はJavaScriptの動作がすごい遅かったが、今はかなり早くなっている。
ほぼ標準技術だけで、プラグインに頼らなくてもアプリケーションが作れる。

IT管理者と新しいIE

シー・ピー・エス 村地さん(@hebikuzure)
(以前 htmlday のHTML朝活会でご一緒させて頂きました。)

IEのアイコンはどんどんシンプルになっているが、実はIEのUIはどんどんシンプルになっていて、中のコンテンツが目立つようになっているから。

IEのEOL予定

  • IE6 : 2014/04/08
  • IE7 : 2017/04/11
  • IE8,9 : 2020/01/14
  • IE10,11 : 2023/01/10

IE7は4年後だが、もしも今4年後のシステムを作っているのであればサポート外にすることも考えられる。

各バージョンのリリース間隔

  • 6->7 : 4 year 10 month
  • 7->8 : 2 year 8 month
  • 8->9 : 1 year 9 month
  • 9->10 : 1 year 7 month
  • 10->11 : ?(about 1 year)
  • 11->12 : ?(shorter than 1 year??)

リリースがどんどん早くなっている。
IEのサポートサイクル(10年)の見直しもあるかも。。。

Windows/IE のバージョン統一がしにくくなる?
バージョン間の動作違いが拡大しないか。
ユーザー教育・ユーザーサポートコストが増大しないか。

n-1ポリシー : 最新版と1つ前までしかサポートしません。
Office365は n-2 サポートなので、Office2007はまだ使われているがサポート外。

どう対策するのか

短期的

■互換モードを活用する。

エミュレートされるもの

  • レンダリング
  • JavaScript
  • DOMの構造
  • CSS
  • User Agent String(互換モードであることはわかる)

互換モード表示方法

  • イントラネットゾーンのサイトは既定で互換モード表示
    社内システムはこのおかげで動いていることもある。
  • ユーザーが互換表示ボタンをクリック(アドレスバーの中にある。IE11では無くなった)
  • サーバーレスポンスで互換表示を指定(HTTPヘッダ)
    • X-UA-Compatible ヘッダー
    • 指定できる値
      • EmulatelEx(7, 8, 9, 10) (ex. IE=EmulateIE7)
      • 数字のみ (ex. IE=7)
      • edge (そのブラウザで表示できる最新バージョンで表示)
  • ページの meta タグで互換表示を指定
    サーバーレスポンスと同じ指定ができる
  • Microsoftが提供する互換表示リスト(CVリスト)で表示

互換モードでも動かないものもある。
Wiindows8のスタート画面のIEには互換モードが無い。

■互換性検証を活用する。

  • 既存ページの問題点を検証する
  • 新しいIEと非互換部分の改善方法を確認する
  • 改善作業スケジュール化する
  • Microsoftが提供している Compat Inspector を使うと簡単

Compat InspectorはJavaScriptで、ページの先頭で読み込む。
互換性スコアがページ内に表示される。
スコアをクリックすると詳細を確認できる。

HTMLを直接書き換えてもいいが、本番の画面を確認するならFiddlerを使ってレスポンスに挿入するといい。
参考:http://www.slideshare.net/hebikuzure/cod2012-room-t1

中長期的

■ロックインを避ける

  • ベンダーロックイン
    • 標準化されていない技術は避ける
    • User Agent/Browser Versionを固定したコードを作らない
    • HackではなくFeature Detection
    • 些細な違いを気にしない
  • バージョンロックイン

■Webの本質に立ち返る

  • クライアントでのインストール
  • サーバーだけで改修が完結する
  • ネットワークに繋がればすぐ利用できる

本来はWebアプリケーションはこういうものだったはずだが、特定バージョンしか動かないとかはおかしい。
柔軟な対応やスピーディーな開発がWeb

後方互換はいつまで維持されるのか

IE11で互換表示ボタンが無くなったのは、MSからの以下のメッセージではないか。

  • 互換表示で時間を買う
  • 互換表示で対応完了ではない
  • 標準準拠に対応させるための時間稼ぎ
  • MSはバージョンアップについて次のステップに進む

だから、IEは業務システムで使われている。いままでもこれからも

マイクロソフト 内河さん

IE11の概要

  • IE11は早い
    TestDriveで検索してPenguinMarkでChromeと比べると全然違う。
    PenguinMark:http://ie.microsoft.com/testdrive/Performance/PenguinMark/
  • タブレット操作を意識したデザイン変更
  • タブの切り替えが早い
  • 家のPCで途中まで見ていたサイトをタブレットからも見られる
  • 標準機能への準拠
  • タブを並べて見比べたりもできる
  • 電話番号を自動認識し、クリックするとSkypeで電話できる

Web標準の取り組みと modern.IE

HTML5、CSS3、SVG、ES6
仕様通りに書けばほとんど動作する。

modern.IE

http://modern.ie/

  • 検証ウィザード
  • 検証のための仮想環境
  • ベストプラクティス

サイト検証だけではなく、改善方法の提案もしてくれる。
クロスブラウザーテストが3ヶ月無料で利用でき、様々なブラウザでどのように表示されるのかを確認できる。

後方互換性

IEの業務システムでの利用率

  • 既定のブラウザー
  • インストール台数

共に最大。
そのため、使い続けて頂くには互換性は重要。

充実したサポート体制。
他のブラウザでは、問題が起きても文句を言う先が無い。

ブラウザ更新の必要性

  • コンテンツが進化しているので、ブラウザーも進化が必要
  • 業務システムでもアップデートを意識
  • セキュリティの面でも必要

新宿鮫:第13回AWSもくもく勉強会 EclipseでJavaからEC2作成

新宿鮫:第13回AWSもくもく勉強会に参加しました。

今日はAWS Toolkit for Eclipseを使用して、JavaからEC2を立ち上げたりしてみたいと思います。
AWS Toolkit for Eclipseは既にノートに入ってるので、インストール方法は上記のリンクを参考にしてください。

ちなみにJava用AWS SDKのAPIマニュアルはこちらにあります。

プロジェクトの作成

新規プロジェクトから [AWS]-[AWS Java Project] を選択します。

f:id:yuji0316:20130731204400p:plain

プロジェクト名は「MokuMokuSDK」で。
初めてなので、とりあえずEC2のサンプルにチェックつけてみました。

f:id:yuji0316:20130731204401p:plain

のこりはデフォルトのまま、プロジェクト作成完了。
これらのファイルが作成されました。

f:id:yuji0316:20130731204402p:plain

プログラム作成

作成されたサンプルはスポットインスタンスだったので却下w
通常インスタンスの作り方をネットでいろいろ拾ってきて、ひとまずシンプルに作りたかったので AMI・KeyPair・セキュリティグループ は既存のを使用しました。

public class MokuMokuEC2 {
    private AmazonEC2      ec2;

    public static void main(String[] args) throws Exception {
        MokuMokuEC2 moku = new MokuMokuEC2();
        moku.create();
    }

    public void create() throws Exception {
        // プロパティファイル読み込み
        AWSCredentials credentials = new PropertiesCredentials(
                InlineGettingStartedCodeSampleApp.class.getResourceAsStream("AwsCredentials.properties"));
        // EC2クライアント作成して日本リージョンを設定
        ec2 = new AmazonEC2Client(credentials);
        ec2.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1));

        // 各種パラメータ設定
        RunInstancesRequest runInstancesRequest = new RunInstancesRequest();
        runInstancesRequest
          .withImageId("ami-19029718")
          .withInstanceType(InstanceType.T1Micro)
          .withKeyName("key-tokyo")
          .withSecurityGroups("test-sec-grp-novpc")
          .withMinCount(1)
          .withMaxCount(1);

        // 起動
        RunInstancesResult runInstancesResult = ec2.runInstances(runInstancesRequest);
        System.out.println(runInstancesResult);
    }
}

これを実行したら、ちゃんとEC2が起動して、デフォルトで立ち上がるようになっているApacheとTomcatの画面も見れました。
SSHでの接続も確認。

課題

サーバーの停止・廃止

時間がなくて、サーバーの起動までしかできませんでした。

サーバー名の指定

指定の仕方がよくわからなかったので、とりあえず無しでやったら empty になってしまいましたw

f:id:yuji0316:20130731205510p:plain

VPC内にEC2インスタンスを作成

最初はセキュリティグループ名にVPC用のグループ名を指定しましたが、

AWS Error Code: InvalidParameterCombination, AWS Error Message: VPC security groups may not be used for a non-VPC launch

と怒られてしまったので、ひとまずnon-VPCのグループを使いました。

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

JAWS-UG中央線 第0回勉強会

東中野在住ってことで、JAWS-UG中央線 第0回勉強会に参加してきました。

Webデベロッパー向けのお話

遅刻して聞けず orz

ヴァル研究所のAWS利用事例紹介

後半から参加で、いろいろ準備しながらだったのであまりメモ取れませんでした。。。

AWSを勉強していると、だれもがなんでもAWSでやりたがる病にかかる。

fluentd使ってログをS3に突っ込むと、普段みるのが面倒。
DynamoDBを使ってみたが、結構お高くもなる。DynamoDB使い過ぎ。。。

まとめ

  • 可用性の向上やチャレンジなどAWSの選択による変化は大きかった
  • 失敗はしたが、それにより本当の良さがわかると思う
  • AWSだけでは解決できないこともある
  • ミドルゥエアを含めいろいろな選択肢を検討しましょう

UserDataでEC2をより便利に

登壇予定だった得上さんが体調不良のため、Amazonの堀内さんが代打で話をして下さいました。

EC2の使い方進化論

  1. コンソールから起動
  2. userdataを使う
  3. AutoScalingで起動
  4. メモ取れずorz

今日はuserdataの話

パラメータを渡す

起動時にパラメータを指定する。
AMIから構築時に userdata:dev とか userdata:prod を渡してインスタンスの設定変えるとか。

どうやって渡すか

  • ec2-metadataコマンド
    ec-metadata -d
    で情報を見たりできる。

  • http://169,254.169.254 にアクセスして渡す
    様々な言語から使いやすい。
    EC2からしか使えないので注意

とりあえず打ってみたらこんな感じでした。

[ec2-user@ip-10-0-0-169 ~]$ ec2-metadata -d
user-data: not available

[ec2-user@ip-10-0-0-169 ~]$ curl http://169.254.169.254
1.0
2007-01-19
2007-03-01
・・・
[ec2-user@ip-10-0-0-169 ~]$ curl http://169.254.169.254/latest/
dynamic
meta-data
[ec2-user@ip-10-0-0-169 ~]$ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
・・・

AWSカルタ

全部で約50枚くらいのカルタを6人テーブルでやって7枚とれました。
最初はみんなおとなしかったですが、どんどん白熱していく感じが楽しかったです。
そして自分の不勉強っぷりを痛感。。。

f:id:yuji0316:20130725201228j:plain

懇親会

AWSの中の方や、会場にもなったヴァル研究所の方々とか、ほかにもAWS好きな方々と熱い話ができてすごく楽しかったです。次回もぜひ参加させて頂きます!

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

NetBeansとGlassFishを使ってJavaEE7のWebSocketを遊ぶ。あとAWSでデプロイとか。

ちょっと前になりますが、最新のJavaEE7がリリースされました。
さらにJavaEE7に対応したNetBeansとGlassFishも出たということなので、WebSocketの実験です。
ローカルで動作確認ができたら、AWSのEC2で動かしてみます。

ローカル環境構築

NetBeansとGlassFishのインストール

まずはJavaEE7に対応したNetBeans7.3.1のダウンロードから。
https://netbeans.org/downloads/

f:id:yuji0316:20130714185208p:plain

"JavaEE"でいいやと思ったけど、サイズたいして変わらないので"すべて"をダウンロードして netbeans-7.3.1-windows.exe を実行。
※JDKがインストールされていないとエラーが出るので、事前にインストールしておきます。

プロジェクトの作成

デスクトップにできた NetBeans IDE 7.3.1 をクリックして起動します。

f:id:yuji0316:20130714185209p:plain

「ファイル」-「新規プロジェクト」でダイアログを開き、「Java Web」からWebアプリケーションを選択します。

f:id:yuji0316:20130714185210p:plain

プロジェクト名は「JavaEE7Test」としておきます。

f:id:yuji0316:20130714185211p:plain

JavaEEバージョンが7になっているのを確認したらそのまま「次へ」。

f:id:yuji0316:20130714185212p:plain

とりあえず今回はフレームワークは何も選択せずに終了。

f:id:yuji0316:20130714185213p:plain

サーバーアプリケーションの作成

プロジェクトのソース・パッケージを右クリックして 「新規」-「その他」を選択。

f:id:yuji0316:20130714185214p:plain

Webカテゴリから「WebSocketエンドポイント」を選択して「次へ」。

f:id:yuji0316:20130714185215p:plain

パッケージ名だけ適当に入力して「終了」。

f:id:yuji0316:20130714185216p:plain

作成されたクラスに以下の処理を記述。

@ServerEndpoint("/endpoint")
public class NewWSEndpoint {

    private static Set<Session> sessionSet
            = Collections.synchronizedSet(new HashSet<Session>());

    @OnOpen
    public void open(Session session){ sessionSet.add(session); }

    @OnClose
    public void close(Session session){ sessionSet.remove(session); }

    @OnMessage
    public void onMessage(String message) {
        for(Session session : sessionSet){
            session.getAsyncRemote().sendText(message);
        }
    }
}

クライアントアプリケーションの作成

プロジェクト作成に作られた index.html を以下のように修正します。

<!DOCTYPE html>
<html>
<head>
    <title>JavaEE7 WebSocket Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script type="text/javascript">
        var socket;
        $(document).ready(function(){
            socket = new WebSocket("ws://localhost:8080/JavaEE7Test/endpoint");

            socket.onmessage = function(message){
                $('#messages').append(message.data + "<br/>");
            }

            $('#send').click(function(){
                socket.send($('#message').val());
                $('#message').val('');
            })
        });
    </script>
</head>
<body>
    <input id="message" type="text">
    <button id="send">Send</button>
    <div id="messages"></div>
</body>
</html>

GlassFishサーバーを起動して確認

プロジェクト名を右クリックして「実行」

f:id:yuji0316:20130714185217p:plain

サーバーが起動すると自動的に index.html のページを開きますが、
開かれない場合はブラウザから
http://localhost:8080/JavaEE7Test/
にアクセスします。

ためしにChromeとIEでアクセスして、IEからメッセージを送信してみます。

f:id:yuji0316:20130714185218p:plain

ちゃんとChromeとIEの両方にメッセージが表示されました!

f:id:yuji0316:20130714185219p:plain

AWS環境構築

今作成したプロジェクトを、今度はAWSのEC2で動かしてみます。

JDK1.7のインストール

ここからJDK1.7をダウンロードしてきます。
直接wgetをすると、規約に同意してくださいというエラーHTMLが帰ってきてしまったので、一度ローカルPCに保存して、S3に上げてからwgetでEC2に持ってきました。

/usr/local の下に解凍し jdk1.7 という名前でアクセスできるようにしておきます。

$ ls -l /usr/local | grep jdk
lrwxrwxrwx 1 root root        11 Jul 14 08:26 jdk1.7 -> jdk1.7.0_25
drwxr-xr-x 8  500  143      4096 Jun  6 04:07 jdk1.7.0_25
-rw-r--r-- 1 root root  96316511 Jul 14 08:19 jdk-7u25-linux-x64.gz

GlassFishのインストール

まずはGlassFishをダウンロードして解凍します。ここでは /usr/loca に置きます。

$ cd /usr/local
$ sudo wget http://download.java.net/glassfish/4.0/release/glassfish-4.0-ml.zip
$ sudo unzip glassfish-4.0-ml.zip

デフォルトのポート番号が8080となっていますが、同じサーバーでTomcatが8080を使っているので、ここでは8000に変更します。 あと、8181のポートも開かれていますが、こちらはとりあえず無効にしておきます。

$ cd /usr/local/glassfish4/glassfish/domains/domain1/config
$ sudo vi domain.xml

変更前
<network-listener port="8080" protocol="http-listener-1" transport="tcp" name="http-listener-1" thread-pool="http-thread-pool"></network-listener>
<network-listener port="8181" protocol="http-listener-2" transport="tcp" name="http-listener-2" thread-pool="http-thread-pool"></network-listener>

変更後
<network-listener port="8000" protocol="http-listener-1" transport="tcp" name="http-listener-1" thread-pool="http-thread-pool"></network-listener>
<network-listener port="8181" enabled="false" protocol="http-listener-2" transport="tcp" name="http-listener-2" thread-pool="http-thread-pool"></network-listener>

設定が完了したらサーバーを起動します。
その際、rootユーザになった後、先ほどインストールしたJDK1.7を JAVA_HOME と AS_JAVA に設定します。

$ cd /usr/local/glassfish4/glassfish/bin
$ sudo su
# export JAVA_HOME=/usr/local/jdk1.7
# export AS_JAVA=/usr/local/jdk1.7
# ./asadmin start-domain
Waiting for domain1 to start .........................
Successfully started the domain : domain1
domain  Location: /usr/local/glassfish4/glassfish/domains/domain1
Log File: /usr/local/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

ブラウザからアクセスできるように、EC2のセキュリティグループで、ポート8000を許可しておきます。

f:id:yuji0316:20130714185220p:plain

ポート8000でアクセスすると、GlassFishの画面が表示されました。

f:id:yuji0316:20130714185221p:plain

WebSocketのプロジェクトを配置

先ほどNetBeansで作成したサーバーアプリケーションをwarファイルにして、AWSのGlassFishに配置します。

まずはGlassFishを停止。ユーザは先ほどrootになったので、そのまま実行。

# cd /usr/local/glassfish4/glassfish/bin
# ./asadmin stop-domain
Waiting for the domain to stop ...
Command stop-domain executed successfully.

プロジェクトを右クリックして「消去してビルド」を選択。

f:id:yuji0316:20130714185222p:plain

ファイルのタブでdestフォルダを見るとwarファイルが作成されています。

f:id:yuji0316:20130714185223p:plain

これをJDKの時と同じように、S3に上げてから、wgetでEC2に持ってきます。
自動デプロイ用のフォルダにwarファイルを配置したら、GlassFishを起動。

# cd /usr/local/glassfish4/glassfish/domains/domain1/autodeploy
# ls -l
total 12
drwxr-xr-x 2 root root 4096 May 14 22:34 bundles
-rw-r--r-- 1 root root 4164 Jul 14 09:01 JavaEE7Test.war
# cd /usr/local/glassfish4/glassfish/bin
# ./asadmin start-domain
Waiting for domain1 to start .................
Successfully started the domain : domain1
domain  Location: /usr/local/glassfish4/glassfish/domains/domain1
Log File: /usr/local/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

サーバーが起動したら、先ほどと同様にブラウザからアクセスしてみます。

f:id:yuji0316:20130714185224p:plain

キター!

この記事をアップしてしばらくはここで動かしておくので、気が向いたら遊んでみてください。別に面白くはないですがw
ただし、送信したメッセージは同時接続している他の人にも送られるので、常識の範囲でおねがいします。

作って覚えるJava―NetBeans入門

作って覚えるJava―NetBeans入門

Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava (Programmer’s SELECTION)

Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava (Programmer’s SELECTION)

  • 作者: Antonio Goncalves,日本オラクル株式会社,株式会社プロシステムエルオーシー
  • 出版社/メーカー: 翔泳社
  • 発売日: 2012/03/09
  • メディア: 大型本
  • 購入: 5人 クリック: 147回
  • この商品を含むブログ (24件) を見る

新宿鮫:第11回AWSもくもく勉強会 ELBを触ってみました

先週に引き続き、新宿鮫:第11回AWSもくもく勉強会に参加しました。

今回はELB(Elastic Load Balancer)でアクセスの振り分け実験です。
ほんとはオートスケーリングまでやりたかったのですが、残念ながら時間切れ orz

アプリサーバーを用意

まずはEC2でTomcat起動。Tomcatのポートは8080を使っているので、セキュリティグループでアクセスできるようにしておきます。
このサーバーでAMIを作って、他のサーバーを立てていきます。
その際、表示されるページが同じだとどのサーバーが呼ばれているか判断できないので、JSPを用意してホスト名を動的に表示するようにします。

<%@page import="java.net.*" %>
<html>
<head></head>
<body>
Tomcat Server (Host:"<%= InetAddress.getLocalHost().getHostName() %>")<br>
</body>
</html>

AMIを作成。名前は MokuMokuAMI

f:id:yuji0316:20130703205719p:plain

AMIができたら、それを選んでLaunch

f:id:yuji0316:20130703205720p:plain

2台のEC2が準備できました。名前はRedとYellowです。

f:id:yuji0316:20130703205721p:plain

ちなみにアクセスするとこんな感じでホスト名が表示されます。

f:id:yuji0316:20130703205722p:plain

ELB(Elastic Load Balancer)の設定

EC2 DashboardにあるLoad BalancersからELBを作成します。

名前はMokuMokuELB
ここではVPC内に作成するので、"Create LB inside"でVPCを選びます。
VPC外からアクセスする必要があるので、"Create an internal ~"はチェックしないまま。
Tomcatへアクセスするために、ポート8080を追加します。
先ほど立てたEC2ではApacheも動くようにしてあったので、ポート80はそのまま残しておきます。

f:id:yuji0316:20130703205723p:plain

"Available Subnets"にあったものを選んで、"Selected Subnets"に移動します。

f:id:yuji0316:20130703205724p:plain

先ほど作成したEC2を両方とも選びます。

f:id:yuji0316:20130703205725p:plain

ELBの設定画面で各インスタンスの状況を確認できます。Status が In Service となっていればOKです。
インスタンスが正常に動作している場合でも、最初はIn Service になるまで少し時間がかかるようです。今回も2,3分ほど待ちました。

f:id:yuji0316:20130703205726p:plain

動作確認

設定画面にあるDNS Nameのポート8080にアクセスします。

f:id:yuji0316:20130703205727p:plain

無事2つのホストが交互に表示されました!
ただ、初めはなかなか切り替わらなかったのですが、なぜか画面のロードが終わってからF5を押して更新してもサーバーは切り替わらず、
F5をダブルクリックして、画面ロード中に再度アクセスすると切り替わるようですw

f:id:yuji0316:20130703205728p:plain

f:id:yuji0316:20130703205729p:plain

DNSが反映されるまでしばらく時間がかかるので、待ちきれない場合はnetstatなどでIPを調べれば表示できます。
管理コンソールからはIPを見ることができないので、裏でIPアドレスが自動に変わる可能性があります。そのため通常はDNS Nameを使った方がいいでしょう。

Java8新機能 ラムダ式とデフォルトメソッドの導入理由

前々回に次回予告した内容ですw
ラムダ式とデフォルトメソッドがどう関係あるのかということですが、まずはラムダ式が追加された経緯から読んでみます。

なぜJavaにラムダ式が追加されたのか

Why are lambda expressions being added to Java?

ラムダ式(とクロージャ)は最近の様々な言語で人気が出ています。これには様々な理由がありますが、Javaにとって最も差し迫った理由は、コレクションの処理を複数のスレッドで分散処理することです。 現在、ListやSetはCollectionから取得されたIteratorを使ってその要素が一つずつ順番に処理されるのが普通です。 もしそれぞれの要素を並列に処理しようとした場合、その責任を負うのはCollectionではなく、プログラマがそういったコードを書かなくてはいけません。

Java8では、様々な方法で要素を処理するためのメソッドをCollectionに持たせ、それを利用するようにすることが目的です。 (例えば、とてもシンプルなforEachメソッドを使用することで、すべての要素に対して処理を行えます。) 利点としては、Collectionが自身の要素に対する反復処理を管理でき、並列処理を行う責任を、プログラマからライブラリに移管できます。

しかしそのためには、その機能を提供するためのシンプルなメソッドをCollectionに追加する必要があります。 現在は、適切なInterfaceを実装した無名クラスを利用するのが標準的な方法です。しかし、無名クラスを使用する方法は、実用面から見て非常に不恰好です。

例えば、CollectionのforEachメソッドが、Consumer Interfaceを引数にとり、各要素のacceptメソッドを呼び出す場合、

      interface Consumer<T> { void accept(T t); }

forEachを使用してListに含まれるjava.awt.Pointのxとyの値を入れ替えるとします。 Consumerを実装した無名クラスを使用する場合、このように入れ替えのためのメソッドを渡します。

    pointList.forEach(new Consumer() {
        public void accept(Point p) {
            p.move(p.y, p.x);
        }
    });

しかし、ラムダ式を使用すると、同様のことがはるかに簡潔に実現できます。

    pointList.forEach(p -> p.move(p.y, p.x));

つまり、反復処理を並列に行うための簡単な方法として、Collection InterfaceにforEachが追加されました。
しかし、そのままだと無名クラスを使用した面倒な書き方をしなくてはいけないので、簡潔に書けるようにラムダ式が追加された。
ということでしょうか。

そもそも並列処理が重要な理由としてマルチコアプロセッサの登場があります。並列処理をさせることで、その能力をフルに活かしたいということでしょう。

ちなみにこのサンプルコードですが、並列処理をさせるためには以前の記事でも書きましたが、parallelStreamを使用して

    pointList.parallelStream().forEach(p -> p.move(p.y, p.x)); 

とする必要があります。

なぜJavaにデフォルトメソッドが追加されたのか

What are default methods?

"Why are lambda expressions being added to Java?"のページでは、各要素を処理する例として、CollectionのforEachの例を使用しています。

    pointList.forEach(p -> p.move(p.y, p.x));

しかし、JavaのCollectionフレームワークは15年前に、こういった機能を考慮せずにデザインされたものです。この機能のために必要なforEachやその他のメソッドが含まれていませんでした。 Collectionクラスにメソッドを追加するということは、高いインターフェースベースのフレームワークを破壊します。 Collectionクラスは、それに依存しているコードの決まり事を定義するInterfaceです。(同様に、ユーティリティクラスのCollectionsにstaticなメソッドを追加することは解決策になりません。) つまり、Interfaceに新しいメソッドを追加した場合、そのコレクションにも反映させる必要があります。 しかし、現在Interfaceにメソッドを追加した場合、それを実装している既存のクラスを変更しなくてはいけなくなります。

これがデフォルトメソッド(virtual extension methodsやdefender methodsとも呼ばれます)を導入した理由です。 Interfaceが既存の実装クラスに影響を与えることなく進化することを可能とするのが目的です。 そのためには、Interfaceの目的を大きく変える必要があります。 以前はJavaDocで動作が定義された抽象メソッドを宣言できるだけでした。一方、現在はデフォルト実装を持った具体的なメソッドを宣言することができます。 例えば、仮にIteratorに要素を1つスキップするメソッドを追加する場合

    interface Iterator {
        // existing method declarations
        default void skip() {
            if (hasNext()) next();
        }
    }

もしIteratorがこのように拡張された場合、すべての実装クラスは自動的にskipメソッドを持ち、抽象メソッドと同様に呼び出すことができます。 skipメソッドが呼び出された場合、実装クラスでこのメソッドが定義されていなければ、Interfaceの処理が呼び出されます。 その代わりに、(デフォルトメソッドは仮なので)Iteratorを実装したクラスはデフォルトメソッドをオーバーライドすることができます。

つまり、ラムダ式(というか並列処理)のためにCollection InterfaceにforEachとかを追加したけど、そのままだとCollectionを実装している各クラスでその処理を実装する必要がでてくる。 そうなると、下位互換もできなくなってしまうため、その解決方法としてデフォルトメソッドが追加されたというわけですね。

Interfaceを進化させるためという理由はありますが、なんというか、将来に向けたビジョンを持ってというよりは、必要に迫られて導入された感じがしてちょっと悲しいですねw

新宿鮫:第10回AWSもくもく勉強会 VPC構築

shinodoggさんに連れられて、新宿鮫:第10回AWSもくもく勉強会に初参加してきました。

以前立てたEC2は外部にそのままさらされていたので、VPCを構築して、その中にEC2インスタンスを立ててみました。

VPCの構築

まずはVPCの構築から

f:id:yuji0316:20130626202737p:plain

ひとまず一番シンプルなやつで

f:id:yuji0316:20130626202738p:plain

デフォルトのまま

f:id:yuji0316:20130626202739p:plain

あっさり完了です。

f:id:yuji0316:20130626202740p:plain

EC2作成

次はEC2を立てます。

AMIはAmazon Linuxで

f:id:yuji0316:20130626202741p:plain

デフォルトではEC2-Classicが選択されていたので、EC2-VPCに変更
最近アカウントを作成した人はデフォルトでVPCに作られるようになっています。
以降もVPC関連の画面で違うことがあると思いますが、適時読み替えてください。

f:id:yuji0316:20130626202742p:plain

デフォルトのまま設定を進めていきます。

Nameには"test_vpc"を指定

f:id:yuji0316:20130626202743p:plain

セキュリティグループはとりあえずSSHとHTTPを許可

f:id:yuji0316:20130626202744p:plain

その後もデフォルトで設定。

完了した後に確認すると、ローカルアドレスが割り振られています。

f:id:yuji0316:20130626202745p:plain

グローバルIPの割り当て

このままだとローカルIPしかなくてSSHで繋げないので、グローバルIPを割り振ります。
AWSではグローバルIPのことをElasticIPと呼んでいます。

ElasticIPsのメニューから、Allocate New Addressを選択

f:id:yuji0316:20130626202746p:plain

EIP used in がデフォルトでEC2だったので、VPCに変更

f:id:yuji0316:20130626202747p:plain

IPが作成されたら、Associate Adressから先ほど作成したEC2インスタンスに紐付けます。

f:id:yuji0316:20130626202748p:plain

InstanceでEC2を選択

f:id:yuji0316:20130626202749p:plain

EC2の画面に戻って設定をみると、ちゃんとグローバルIPが割り振られています。

f:id:yuji0316:20130626202750p:plain

HTTPサーバーを立ち上げてアクセス

Apacheをインストールして起動

[ec2-user@ip-10-0-0-123 ~]$ sudo yum -y install httpd
[ec2-user@ip-10-0-0-123 ~]$ sudo /etc/rc.d/init.d/httpd start

ブラウザから無事アクセス出来ました

f:id:yuji0316:20130626202751p:plain

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド