Alfred workflowで新規ウィンドウを開く

最近、Alfredを使い始めました。

どうせなら、ということでPowerPackも買って、workflowを使えるようにしました。

とか入れてます。

で、それなりに便利に使ってたんですが、FinderとかiTerm2を起動しようとして、別のデスクトップに起動してたのがアクティブになるのが不便。。。

というわけで、下記を追加してみた。

Finderを新規に起動する

  • Alfredの設定画面を開く
  • Workflowsタブを開く
  • 左ペインの右下にある"+"を押す
  • Templates -> Essentials -> Keyword to AppleScript を選択する
  • keywordをダブルクリックする
    • Keywordに"nfinder"を入力
    • No Argumentを選択
    • titleに"new finder"とかを入力
  • Run NSAppleScriptをダブルクリックする
on alfred_script(q)
  tell application "Finder"
    make new Finder window
    set frontmost to true
  end tell
end alfred_script

上記手順により、Alfred呼び出し -> "nfin"とか入力 -> Enter でFinderが新規に起動します。

iTerm2を新規に起動する

Finderの時と手順は同様。
keywordは"niterm"にしました。
AppleScriptは下記の通り。

on alfred_script(q)
    if application "iTerm2" is running or application "iTerm" is running then
        run script "
          on run {q}
              tell application \":Applications:iTerm.app\"
                  create window with default profile
                  select first window
                  tell the first window
                      if onlywindow is false then
                          create tab with default profile
                      end if
                      tell current session to write text q
                  end tell
              end tell
          end run
      " with parameters {q}
    else
        run script "
          on run {q}
              tell application \":Applications:iTerm.app\"
                  activate
                  try
                      select first window
                  on error
                      create window with default profile
                      select first window
                  end try
                  tell the first window
                      tell current session to write text q
                  end tell
              end tell
          end run
      " with parameters {q}
    end if
end alfred_script

これも、Alfred呼び出し -> "nit"とか入力 -> Enter でiTerm2が新規に起動します。
https://gist.github.com/reyjrar/1769355 を参考にしたのですが、zshを利用していたので書き換えました。

アイコンとかサクッと作れれば、フツーに公開するんだけどな。。。

KFCocoaPodsPlugin をインストールしてみる

前に iOSアプリ開発が捗るXcodeプラグイン - Qiita [キータ]ricobeck/KFCocoaPodsPlugin · GitHub というプラグインが紹介されていました。

便利そうだなーと思いつつ、放置していたのですが、年末年始で少し時間が出来たので、導入してみました。

ただし、githubの説明が

Clone this repo or download the zip, run 'pod install' in the terminal, open the workspace file in Xcode and compile. After a restart of Xcode you have a 'CocoaPods' Menu Item in the Products menu.

しか無かったので、念のためメモ。
※cocoapodsはインストール済みの前提

手順

今回、 ~/bin に入れておくとします。

cd ~/bin
git clone git@github.com:ricobeck/KFCocoaPodsPlugin.git
cd KFCocoaPodsPlugin
pod install
open KFCocoaPodsPlugin.xcworkspace

Xcodeが開くので、Product -> Buildとし、Xcodeを一旦完全に終了させ、再度起動。

すると、公式のgithubにあるように、Productメニュー無いにCocoaPodsが表示されます。
これで入力補完も効くし、黒い画面が無くてもpod install が出来ます。

SeleniumをRubyから呼んでみる

Gemfileを作って編集する。

bundle init
vim Gemfile

入力内容は下記の通り。

source "https://rubygems.org"
gem "selenium-webdriver", "‾> 2.38.0” 

bundle installを実行する。

bundle install --path vendor/bundle 

rubyスクリプトファイルを作成する。

vim drive.rb

内容は下記の通り。

require 'rubygems'
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox
driver.get "http://google.com"

element = driver.find_element :name => "q"
element.send_keys "Cheese!"
element.submit

puts "Page title is #{driver.title}"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { driver.title.downcase.start_with? "cheese!" }

puts "Page title is #{driver.title}"
driver.quit 

実行してみる。

ruby drive.rb

怒られる。selenium-webdriverが読み込めない模様。

`require': cannot load such file -- selenium-webdriver (LoadError)

bundle exec で実行してみる。

bundle exec ruby drive.rb

怒られる。firefoxがインストールされてないから?

Could not find Firefox binary (os=macosx). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path= (Selenium::WebDriver::Error::WebDriverError)

chromeに変えてみて、再実行。やっぱり怒られる。chromedriverが無いとダメらしい。

Unable to find the chromedriver executable. Please download the server from http://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver. (Selenium::WebDriver::Error::WebDriverError)

言われたとおり、http://chromedriver.storage.googleapis.com/index.html をブラウザで開いて、最新版(2.7)のmac用をダウンロード。 解凍すると、 chromedriver というファイルが出てくるので、PATHが通っているディレクトリに移動。

で、再実行。

bundle exec ruby drive.rb

無事ブラウザが開き、googleの検索結果が表示され、消えた。 コンソールには

Page title is Google
Page title is Cheese! - Google 検索

が表示されてた。

・公式のサンプルコードなど
http://docs.seleniumhq.org/docs/03_webdriver.jsp
・参考になりそうなところ
http://qiita.com/tomerun/items/9cb81d7a98150ff22f53
http://morizyun.github.io/blog/selenium-scraping-webdriver-ruby/

doubleのまま計算を続けると、計算誤差が増えるって話

doubleでの計算は、計算誤差が生まれるよ、っていう話。

a の値が正確に"0.9"ではないため、どちらにせよ誤差が生まれるけどね。

コードレビューしてて、doubleだけで計算してるのがあった。。。
小数点を含む計算って、BigDecimalを使うのが当たり前じゃないのか・・・?

iOS用ウェブアプリで出来ないこと

iOS上で動作するサービスを作成しようと思った時、下記のような選択肢があるかと思います。

  • ネイティブアプリ(Objective-C で作るようなもの)
  • ブラウザアプリ(HTML / JavaScript で作るようなもの)

それ以外にも、それらを組み合わせた

  • ハイブリッドアプリ(Objective-C で作った中に、HTML / JavaScriptで作った画面を入れるようなもの)

もありますね。

今回、ブラウザアプリ(Webアプリ?)を作った際に、ネイティブだったら出来るのに、と思ったことを中心にまとめてみます。 (Androidでも、大体同じことが言えるかもしれません)

PUSH通知

ユーザの呼び戻しには、PUSH通知が有効化と思いますが、ブラウザアプリでは実現できない。

  • メールアドレスを取得し、それを利用する
  • SNSを活用する

あたりで、うまくユーザを呼び戻す必要がある。

クリップボードの利用

PCブラウザでは、「クリップボードにコピーする」ボタンを見たことがあるかと。
これは Flash を利用しており、iOSでは動作しない。
input タグを用意しておき、そこをタップした時に、全選択→iOS標準の「コピー」が表示されるという風にする、というのが妥協案かと。

消えない(消せない)情報を保存する

ネイティブアプリなら、KeyChain が使える。これに入れておけば、アンインストールしても消えない。(はず
ブラウザアプリの場合、データの保存場所としては、Cookie, localstorage などがあるが、 「Cookieとデータを消去」で簡単に消せる。
消されて困る情報は、サーバに保存することになるが、その情報と付き合わせるために、ユーザ認証が必要になる。

特定の環境下で動作させる(Safariだけで動作させる)

ブラウザアプリの場合、Safari 以外で動作する可能性がある。
例えば、Chrome, Operaといったブラウザアプリ、Facebook, TwitterといったSNSアプリなど。
そのへんを、User Agent である程度判定できるが、その後の操作はユーザ任せになる。
そもそも、アプリ側で提供されていないと、Safariで表示させることは不可能になる。

受託の場合は、どこまで対応するか・どのように対応するかなどを、最初に決めておかないともめるかも。

フルスクリーン表示

可視領域を広げる、没入感を与えるといった効果がある、フルスクリーン表示ですが、ユーザに強制することは出来ない。
meta タグなどを利用し、「ホーム画面に追加」を行ってもらい、そこから起動してもらえば、可能。
http://mawatari.jp/archives/web-apps-like-native-apps

アプリがインストールされているかを確認(2013/12/3 追加

アプリがインストールされていたら、アプリ起動ボタンを表示し、
アプリがインストールされていなかったら、アプリダウンロードボタンを表示する。
みたいなことは出来ない。

http://havelog.ayumusato.com/develop/javascript/e564-url-scheme-fallback.html こちらにあるように、URLスキームで起動してみて、画面が切り替わって無ければ、ストアへ飛ばす。という動きなら出来る模様。
ただし、見た目はあんまり綺麗には出来ないみたい。(標準のアラートが出てしまったり

Webとネイティブを提供していて、ネイティブも紹介したいだけなら、App Bannerを使えばいいと思います。 https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html

まとめ

いろいろ制約はありますが、Objective-Cエンジニアを必要としないのは、人的リソースの確保はしやすいかも。
ただし、ちゃんとした HTML / JavaScript を書けるエンジニアを探すのも難しいかも。(有象無象が多いイメージ

appleへの申請を必要とせず、好きなタイミングで、全てのユーザに同じ動作環境を提供出来るのは、魅力的だと思います。

他にも、思い出したら・気がついたら追加しようと思います。

第四回 #渋谷java に参加しました

参加してきました。(スポット参戦中のプロジェクトから抜けて)

まとめ

  • Grails 使ってみるのはありかも
  • groovy 触ってみようかな(とりあえずテストからかな?)
    • そのときはSpock を使ってみよう
  • Gradle もそろそろ使いたいなー
  • JUnitにおけるオブジェクトの等価比較って、他の人も悩んでたんだなー
    • コード補完で頑張る以外にも、がんばれば方法はあるんだなー(JSONPath で除外はありかも)
  • Servlet のURLって、きれーに出来ないのかなーって思ってたけど、UrlRewriteFilter を使えばよかったのか
  • Reactive Extensions って、うまく使えれば便利そうだなー
    • ただし、Java8のラムダを使わないと記述量が増えそう
  • 並行処理とか、真面目に学ばないとなー
  • テンプレートエンジンって、色んなのがあるんだなー
    • Mayaa につづき、Thymeleaf ってのもあるんやなー
      • 個人的には、Java, JS 両方で出来るらしい、Mustache(Handlebars?) を、まずは使ってみたいけど
  • Juzu Web Framework は、、、まぁ、いいか。

感想

  • こういう、色んな技術を知れる場はいいですね〜
  • 仕事が無ければ、もうちょっと他の参加者と話してみたかったけど、残念

雑多なメモ


http://www.slideshare.net/kazuhiroserizawa988/shibuya-java4op

・_y_u_さん Grailsのちょっとイイ話
http://www.slideshare.net/sudoyu/20131116-shibuyajava-grailsgoodness


 NTTソフトウェアの Grails推進室の方

JGGUGの方

Grails
・WebアプリケーションフレームワークRuby on RailsのJavaVMで動く奴てきな
・XML設定不要
 Groovyのコードで書ける

イイところ

Javaの世界と地続き

JVM環境から逃げたいって人いないですよねー。

中身(一部)
Spring Framework
Hibernate
Apache Tomcat Embed 7
Apache Ivy
H2 Database

ほとんどのServletコンテナで動く

性能
http://www.techempower.com/benchmarks/
Scala/Lift, Play、Ruby/Rails より速い!


Javaの資産の活用

・Grailsアプリはただのwar
 いままでの運用ノウハウが活かせる
・Spring / Hibernate の経験が活かせる
 学習コストが抑えられる

Groovyで書ける

クロージャ
メタプログラミング / MOP
AST変換
 DSLを簡単に作れる
Groovy-JDK
 演算子オーバーロード
チェック例外のチェック省略

本:プログラミングGROOVY


Spockでテスト

JGGUGのワークショップ資料をご覧ください

GVM
 rbenv
 Goとかぶってる・・・
Grails wrapper
 Gradle wrapper チェックアウト→コマンドでインストールが不要
Grails console
dbconsole
 DBの中身をWebから見れる
プラグイン機構
 Security coreとか(View, Controller, Serviceとかがはいる)
Serviceとトランザクション
 勝手にトランザクション


デメリットいところ

Checkstyle / Findbugsが使えない
 CodeNarcを使うことになる
パートナー探し
 Spring / Hibernateの経験があれば!
メモリフットプリントが大きい
 PaaS利用では大きなデメリット

ログ出力
 log4j内蔵
スタックトレース
 development モードで画面に出てくる
マルチデータソース
 デフォルトで対応
NoSQL
 プラグインで対応
Hibernateを使いたくない / SQLを生で書きたくない
 HibernateのネイティブSQL API
 Groovy SQLを使う(キャッシュ管理?が必要)
 MyBatis
Grailsプラグインの一覧
 list-pluginsコマンド
Grailsに対応しているIDE
 IntelliJ IDEA が一番いい
Struts1からの移行
 変態プラグインがある
Grailsの書籍
 2.x系に対応した日本語の書籍は無い
 本家のドキュメント


実際の案件で20件ぐらいやってる
ものすごい大規模システムで使ったよ、というのはまだない




jfluteさん MySQLJDBCドライバに振り回されるDBFlute

フリープログラマーさん
現場での教育や、フレームワークの拡張とかやってます

中がGroovyで出せる
0x1f004


MySQLさん
なぜあなたは、バッチ更新しないの?
for文で回っとる
別マシンへの通信コストとかあるから、ちゃんと考えようねって教えてたのに。。。
まじでー

MySQLさん
なぜあなたは、 カーソルフェッチしないの?
数十万件ぐらいだったら、メモリ上に全部乗っかる
本番運用に入って、大量の会員を抱えたあとに発生する(結合テストとかではみつからない)
fetchSize に Integer.MIN_VALUE を設定すると、1件ずつの取得になる
 MIN_VALUEって、、、
い、Integer.MIN_VALUE技!?
closeしないから、新しいSQLを発行出来ない。。。

sql_calc_found_rows
limitが無かった時の件数が取得できる
→MySQLちょっとやるじゃn



grimroseさん Gradleについて
https://github.com/grimrose/shibuya-java-04

Gradleって何?

現在 version 1.8
世界で一番イケてるビルドツール

本:WEB+DB PRESS val.76
 英語ならオライリーにある
Gradle 日本語ドキュメント
 実験的なところは追いついてないところもある


AntからGradle

build.xmlのインポート
17章に書いてある

project: "Ant + Ivy”


MavenからGradle

project: “maven”
ひな形プロジェクト 1.9からコマンドが変わってる
 pom.xmlから生成可能
maven plugin→使えません

コスト と メリット
mavenのレールから外れてる
pom.xmlがツライ
pluginをそんなに使っていない
使いたいpluginがみつからない
→上記に当てはまるひとは gradleへ

“mvn …”.execute()


プロジェクトに柔軟性を
・gradle wrapper
・custom task or plugin
・task test
・groovy





komiya_atsushiさん Junitのオブジェクト透過比較を怠けたい
https://github.com/komiya-atsushi/shibuya-java4

代々木の緑色の会社(渋谷じゃない)

#TokyoWebmining 事務局


「あるメソッドから返却されるオブジェクトの内容が想定しているとおりか?」をテスト

Dto
  List
    BookDto

アプローチ
・assertThat() をひたすら並べる
 →つらい
・equals() を実装する
 →普通にやるのはつらい、Commonsつかう?
・専用のMatcherを実装する
 →テストコード量が増える

汎用的な透過比較 Matcher を実装してみた
komiya-atsushi/shibuya-java4

IsEquivalentTo の概要&機能
・データ構造を再帰的にたどる
・equalsをオーバライド
・Json-path的な記法で
・比較的親切(?)なメッセージ


他の人の意見としては、
・コード補完でがんばる
・toStringでわりきっちゃう



kazurofさん UrlRewriteFilterに手を入れてみた
http://sssslide.com/www.slideshare.net/kazurof/urlrewritefilterissue120

外向きには綺麗なURLを書き換えるライブラリ

外部:/data/123/…
↓
内部:/data/get.do?id=123…

3系→4系
URL変換動作の${…}の
関数の連続はNG
ネストはOK

木構造で解釈
Interpreterパターン

実際に実装してみることが大事ですね



ngsw_taroさん RxJava使ってみた

夢と魔法の待ち時間
https://play.google.com/store/apps/details?id=com.taroid.parkwaittimegetter

自称Kotlinエバンジェリスト

Reactive Extensions のJava実装

LINQのデータソースをイベントと非同期処理に拡張したもの

・学習コスト若干高め
・ 書きやすい、読みやすい
・SAM無名クラス(Java8 早く、、、)



azusaさん 真にスレッドセーフなHashMapとは
http://www.slideshare.net/setoazusa/hash-map-28306457

そのクラスが使われるコンテキストに強く依存する

本:Java並行処理プログラミング

タイトルは釣り

ConcurrentHashMap使えばいいんじゃね?
新規なら、それ一択

無条件には置き換えられない
HashMap extends AbstractMap
ConcurrentHashMap extends AbstractMap

HashMap の値にnullは入る
ConcurrentHashMap の値に nullはNullPointerException

synchronizedMap を仕方ないので使う 
ループするときは呼び出し元で同期しないといけない

シリアライズは同期できない

ひっかかったケース
HttpSessionにHashMapを格納

スレッドごとにオブジェクトを分割すればいい


まとめ
コレクションAPIには地雷があります

スケールアウトの容易さという点では、railsが羨ましい

Java並行処理プログラミング を読みましょう 



eiryuさん Thymeleafのすすめ

TwFavViewの作者

Javaのテンプレートエンジン
たいむりーふ
最新は2.1系

ブラウザで見てもJSPのように崩れない

spring統合用のモジュールがある

属性にth:をつけるだけ
 data-xxxみたいなのはth:attr
マニュアルは短いから、全部読めばいい
サンプル:stfm

th:text
th:each
th:remove=“all-but-first"

JavaScript inlining
 URLとか、言語対応とか

JSP書いてた人なら問題なく書けるはず
 スクリプトレットもりもり使ってなければ

ブラウザで確認できることはかなり便利

デザイナさんとルール
XHTMLで記述する
JavaScriptで扱うためのclass名は、”js-“で始める
極力デザイナー作成部分は触らない。逆もまた然り。
 追加するイメージ

デメリット
th:ifの制御
ヘッダ、フッタなど、include はコピペしないといけない
Spring以外では、そんなに、、、




seri_k 謎のWAF Juzu FrameWorkを試してみたリベンジ

 あんまり使われてない?
play 1.x系に近い

ViewとController機能のみ薄いフレームワーク
template は groovy ベース
Annotationで機能や設定を指定

mavenでベースをサクッと作れる

Annotation Processing を利用する
factory pathにjuzu-core.jar 

更新を検知して、ファイルが消えちゃう。。。?
 cleanすると、再生成

JJUG CCC 2013 Fall に参加しました

ざっくりとしたまとめと感想。

テーブルに電源が備え付けられて無いのは辛かった。macbook air買ったほうがいいのかな。Pro重いし。

基調講演-1

http://www.slideshare.net/yusuke/jjug-ccc-2013fallkeynoteshare

  • IoT (Internet of Things)
  • デバイス数はどんどん増え、一人あたりのデバイス数も増える
  • 開発者が開発し、サーバにデプロイし、それをユーザが利用する、という明確な区分がある
  • →ユーザの現実世界での行動によって、サービスが提供される、それを開発者が制御する、という流れに変わるかも
  •  エンジニアに必要なスキルが変わっていく可能性がある

らしい。ちょっとした恐怖ですね。

基調講演-2 2013 エンタープライズ Java 最前線

  • 急にTシャツ投げが始まる
  • Glass Fish 4からは商用サポートを行わない(Glass Fishが消えるわけではない)
  • 代わりにWebLogicを使えばいい
  • Java EE 7
  • Project Avatar
    • [ここ]をみれば試せる
    • サーバ側をJavaScriptで実装出来る
    • Nashorn(なずほん)上で動作する
    • Javaを使わず、JavaScriptで全てを実装しろ、という訳ではなく、選択肢として提供したという形
  • J2EE時代からは随分変わっているので、やってみて下さい

Project Avatarを仕事で使う日が来るのかなぁ。。。

H-1 ジェネリクスの基礎とクラス設計への応用

テーマ: Generics Hell(4,5回言ってた)

  • Java1.4まではダウンキャストが必要だった(型安全じゃない)
  • Java1.5からはジェネリクスによって、コンパイラ時点で間違いに気づける
  • ジェネリクスとは、inとoutの型の関係性を表すもの
  • 3種類ある
    • 型変数の宣言
    • 型変数のバインド
    • パラメータ化された型
  • Map<String, Map<... とかやらずに、適度なレベルで型を宣言しよう
  • 型変数の境界
    • class Hoge <T extends B>
    • class Hoge <T extends B & Serializable> でインターフェースを境界に加える事が出来る
  • 再帰ジェネリクス
    • abstract class Hoge<T extends Hoge<T>>
    • new でバインド出来ないので、継承で使う
    • 自分自身のクラスを返す・引数にするメソッドを宣言できる
  • 内部クラスのジェネリクス
    • 内部クラスは外部クラスの型変数を利用できる
  • リフレクション
    • java.lang.reflect.Type を返すメソッドから、ダウンキャストして使う
  • 困ったら @nagise さんへ
  • Generics Hell本を書いています

意外と知らないこと・明確にわかってなかったことが多かった。

R2-2 テンプレートエンジンを利用して、プログラマーとWebデザイナーが共同作業をする上で大切なこと

1年半ぐらい自分が悩み続けてたり、現在進行形で同僚が直面している問題の一部だったりする問題。

プログラマ目線

  • 従来:デザイナがHTMLを作成 → プログラマJSPに移植
    • 工数がかかる、開発スピードが遅い、つまらない作業
  • デザイナが直接テンプレートを書ければよい
  • Mayaa を使ってます
  • 使う上で工夫した点
    • m:idの命名規則が重要
      • IF_xxxx
      • LOOP_xxxx
      • xxx_HERE
      • xxxx_TAG
    • 共通部品:サーバサイドincludeの再現
      • iframeを使って擬似的に再現(javascriptで高さ調整、chromeでは表示できない、firefoxとかで)
    • m:id一覧表を自動生成
      • MayaaXMLファイル→SAXでパース→Mayaaを使ってHTMLに変換
    • 相対パス自動調整機能を徹底活用
    • 属性をパラメータとして使用する→m:idが多くなりすぎることを防ぐ
      • 標準では実装されていない
    • Mayaa ファイルを毎回コピペしなくて済むようにする
      • 差分を書き、それを読み込む

デザイナ目線

  • デザイナが読み取れるのは、命名規則とドキュメントのみ(実装などは見てもわからない)
  • 機能が増え、時間が足りなくなると、混沌としてくる
  • ドキュメントはきちんと書き、情報を探せるようにする
    • WordPressがデザイナに人気なのは、そこら辺がしっかりしているから

それらを踏まえて

  • 相互理解が大事
  • プログラマはHTML/CSSの問題を切り分け、デザイン修正の手伝いが出来るように
  • デザイナは最終的にプロダクトを制作しているという責任感を持つ
  • デザイナのPCにサーバ開発環境をインストールさせない
    • 何か問題が起こったら、毎回フォローしないといけない
    • 容易に試験できる環境を用意する
  • 勝手なことをしない

マークアップをお願いするプロジェクトをやるときは、Mayaaを使ってみたいと思った。
JAX-RS + backbone.jsなら、そもそも不要?)
ただし、事前に規約などは取り決めておく必要があることがわかった。
デザイナのPCに開発環境をインストールさせないというのは微妙かもしれない。デザイナさんのスキル次第かと。

H-3 ユニットテスト改善ガイド

  • ユニットテストにまつわる10の勘違い
  • 本:JUnit実践入門がおすすめ
    JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

    JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

  • ユニットテストは簡単なものではない→ちゃんと学ぼう
    • 学習は、プロジェクト外のコストとする
    • 可能な限り業務時間内で
  • まずはユーティリティクラスのテストを書こう
    • 入力に対して出力が一定のメソッドはテストしやすい(副作用がある・状態に依存するものは難しい)
  • テスト対象がテストしづらい場合は、テスト対象を修正する
  • CIを導入する前に、テスト文化を作りましょう
    • CIはローカルでとりあえずやっておくのもOK
  • テストコードもリファクタリングしましょう
    • 継続して使うことに意味があるので、単発プロジェクトではペイできないかも
    • フィクスチャの外部化、RuleやカスタムMatcherの作成、フレームワークを拡張などでリファクタリング
  • デバッガを使う代わりに、テストコード
    • テストコードを書くことを強制し、メンバーの手間を増やすことになると、うまくいかない
  • 上司を説得する材料として、品質向上はNG、教育(スキル向上)のためと説明しよう
    • リグレッション防止を押し出すのもあり
  • 失敗のままのテストは直ぐに修正する、出来ないのならば捨てる
  • 納品物としてテスト仕様書が求められるのであれば、可能な限り省エネで作りましょう
    • JavaDocを印刷とか、カバレッジレポートとか(数字の意味は事前にする)
    • どうしても重荷になるのであれば、いろいろ諦める
  • テスト対象のコードを変更できない環境なら、諦めましょう
    • テストのしにくいコードとはどういうものかを学べる
  • レガシーコードのテストを書こうとしない
    • テストできないからレガシーコード
  • リソースが足りない場合、導入してはいけない
    • プロジェクトが失敗した場合、導入したせいにされ、次からやりづらくなる

テストコードは全てを対象に出来るわけではないと、理解していたつもりだったが、プロジェクトの状態などによって、適用できない範囲は結構多いことがわかった。
基本的に余裕のないプロジェクトばかりなので、ユーティリティクラス・メソッドのデバッグの代わりから初めてみようと思います。
その前に、途中になってるJUnit実践入門を読む(写経する)のが先だけど。。。

R2-4 Javaアプリケーションサーバ構築・運用の勘所

http://www.slideshare.net/TakahiroYamada3/essence-of-javaapplicationserver

※初心者向けのセッションです。※

が嘘だと思ったのは私だけ?(私がこのへんを知らなすぎるだけ?)

R1-5 Javaで作るリッチなWebシステム開発の今

http://www.slideshare.net/kawada_hiroshi/html5webjava3

すごい勢いで喋ってた

  • 従来型:サーバでページを生成する
  • 次世代型:サーバはRESTインターフェースを提供し、JSでページを生成する

  • tools

    • とにかくたくさんある
    • Visual Studio, SenchaSDK は整合性が非常に高い
    • Eclipseとか使うとばらばらだが、新しいものを組み合わせられる
    • サーバの開発ツールはIDEのプラグイン拡張だけど、フロントの開発ツールは黒い画面を結構使う
    • デファクトはGrunt
    • サーバとフロントが、それぞれ独自の道に走っている
  • architecture
    • 5年前の主題はいかに繋げるか、だったが、ここ数年でレイヤーが上がった
    • Java(JAX-RS) + Backbone.js(sync) が鉄板っぽい
    • Project Avator がいい感じになってくれるのではないか
    • jQueryの恐怖
  • formats
  • エンタープライズ分野では、Web技術は敬遠されている
    • しかし、Javaも昔はそうだった
    • JavaScriptの性能も上がっている

スピーカー交代

  • 従来型と次世代型を混ぜると危険
  • JAX-RS + フロントMV*なら、デザインを自由に出来る
    • フロント側の実装量は増える
    • 初期表示までのコストは高い
  • JSFは、デザイン・動きを制限される
    • フロントの実装量は減る(減らして問題ないアプリケーション以外では適用しづらい)

Gruntを知らないっていう人が結構多かったのは意外だった。
エンタープライズJavaでは使わないか。
JAX-RS + Backbone.js をどこかのプロジェクトで使ってみたい。

R2-6 [BOF] JVM言語パネルディスカッション

  • Scala
    • オブジェクト指向+関数型のマルチパラダイム
    • pimp my library で継承出来ないものを拡張出来る
    • IDE, Web Application Framework などが充実
    • Javaと相互に呼び合える(一部、記号などは呼べない)
    • コンパイルが遅い(TDDのリズムが崩れる)
    • Twitterで使われている
    • Effective Scala
    • pimp my libraryを下手な人が書くと...
    • ドメインモデルから書き起こしやすい
    • 既に、事例での説得はしやすい
    • ゲリラ作戦でツールを作ってしまったり
  • Clojure
    • 型なし
    • Lisp方言
    • 試してみたいのなら、Leiningen がおすすめ
    • マクロが使える、文法を作れる
    • Javaと相互に呼び合える
    • Emacsで書く人が多いが、Light Tableも良さそう
    • ニャンパスで使っており、AdThrottle、baasday などで実績あり
    • Herokuで動く
    • 日本語情報が少ない
    • JVMで動くLisp
  • Kotlin
    • 静的型付け言語
    • 簡潔、安全に書ける
    • Androidで動く、JavaScriptに出来る
    • 型安全、Null安全
    • 安定版はまだない
    • Javaと相互に呼び合える
    • IntelliJのプラグインで、Java変換後のコードをプレビューしながら書ける
    • 日本語情報が少ない
    • もっと関数型っぽく書けてもいいんじゃないかと
    • Scalaと違って、とっつきやすい
    • Javaからの移行も楽
    • ビルドは速い
    • Null-Safety
      • NotNull, Nullableを言語でサポートされている
      • val name: String; にnullを代入しようとすると、コンパイルエラー
      • val name: String?; にはnullを代入出来る、nullチェックせずに関数呼び出しを行うとコンパイルエラー
      • name?.toUpperCase() を使えば、メソッドチェーンがしやすい
  • Kink
    • プロトタイプベース
    • オレオレ言語( http://www.slideshare.net/miyakawataku/kink-jvm
    • 言語仕様が小さい(代入も関数呼び出し、トレイとも言語仕様じゃないけどできる)
    • Kink→Javaは可能(逆は無理)
    • 実行速度は遅い
    • 静的解析は言語仕様的に難しい
  • Groovy
    • Javaベースの構文(Javaで書いて、拡張子を変えるだけで、Groovyのファイルに)
    • 動的、MOP(Meta Object Protocol)、AST変換
    • Javaと共存しやすい:テストコードだけ使う、変更の多いViewに近いところだけ使う
    • 最近は静的な部分が充実→高速化
    • Javaと相互に呼び合える(動的な部分は無理)
    • アクセス修飾子は飾り(Javaのprivateメソッドも呼べる:テストできる)
    • Invoke Dynamicを有効にもできるが、遅くなるかも
    • Power Assets
    • 日本語情報が少ない
    • Grails
    • 開発に便利なものはじゃんじゃん入れている
    • 知名度の向上、実績を作ることが必要

Scalaって、やっぱりコンパイルに時間がかかるよね。
テストコードにGroovyを使うのはありかもしれない。private呼べるし。それがいいことなのかは微妙だけど。
Clojureも良さそうだけど、まだLispをやる気にはなれてない。
プロダクションコードに使える(いろんな意味で使いやすい)ものは、Scalaぐらい?Groovyもいけるか?

見てなかったけど発見したスライド

出てないけど発見したLTのスライド

その他雑多なメモ

・キーノート
緑のあんちくしょう
JavaMEはSEと統合されていく方向
IoT(Internet of things)
開発してデプロイ→人間の行動によって、サービスを提供する


・エンタープライズJava最前線
Tシャツ投げ
伝説の謝罪会見?
GlassFishについて
今週の月曜日にロードマップが公開された
GlassFish4からは商用サポートを行わない
GlassFishは参照実装として、残り続ける
商用サポートが必要なら、weblogicなどを利用してください

Java EE 7
JSF2.2, JAX-RS, EL, JMS は大幅な更新
Concurrency, Batch, JSON, WebSocket は新規追加
JavaEE6を学習し、そこから差分を追いかければよいかと
JavaEE7に対応したアプリケーションサーバは現在2つぐらい(JavaEE6は18社)
WebSocketはPOJOベースで簡単に実装できる

CDI, JTAで、いままでのEJBを置き換えられる
Bean Validationが様々なところで使えるようになった

JavaEE7
Web Profile(軽量版) or Full
JAX-RSがWeb Profileに含まれるようになった
WebSocketのクラスタ構成も簡単にできる

Project Avatar
Downloadすると、Avatar込みのGlassFishが落とせる
HTML5アプリ構築フレームワーク
(
JavaSE8ではJavaScriptのエンジンが提供される(ぷろじぇくとなずほん)
ぷろじぇくとらいの で前から動かせていた
 パフォーマンスが20倍ぐらいになる
 Infork dynamic を使って再実装
)
サーバサイドJSとJavaEEアプリの融合
Thin-Server アーキテクチャ(TSA)
今まではViewとModelをサーバ側でマージしていた
ViewとServiceをサーバ側で提供し、クライアント側でViewとModelをマージ
 ModelとServiceをJSONで通信する
View(UI Node)
Avatar(Controller)
Model
がブラウザ上で動作する
Modelに対応するService
Avatar
Dataプロバイダ
がNashornで実装

1. Avatarアプリの作成
avatar new [project-name]
デフォルトでViewが生成される
2. ViewとServiceを実装
service にjs(サーバサイドで実行される)
view にhtml
avatar.registerPushService でurl と実装を指定
scriptタグのdata-model属性などで
outputタグにEL式でデータを与える
3. ViewとServiceをコンパイル
avatar compile [project-name] でコンパイル
service, view以下にbinが出来る
asadmin deploy [project-name] でデプロイできる
4. ViewServiceの「複数ページの一括」ダウンロード(プラグインは不要)
5. WebSocket/Server-Sent Event/RESTfulでDataServiceを利用
6. サーバ側はJavaEEのServiceも利用可能
7. JPA, JMS, NoSQL等のサーバリソースも利用可能
avatarからJavaEEのサービス・アプリケーションを呼び合える
8.クライアント側はHTML5,DOM,ローカルストレージなどを利用可能

JDK8が必須。その後にavatarをダウンロード
yoshio3.com 初めてのProject Avatar

JavaEE8とその将来
JSON-B

J2EE時代からはだいぶ簡単になってるので、やってみて下さい

avatarについて、JavaをやめてJavaScriptで実装するのはどうなんだ
→提供側としては、様々な選択肢を選べる状態にしていきたい
 JavaScriptで全てを置き換えるのは不安だろうだし、工数もかかると思うので、信頼性のあるJavaを使ったり適材適所で使い分けられるように




・ジェネリクスの基礎とクラス設計への応用

導入編
Java1.4まではArrayListから取得するときに、ダウンキャストが必要だった
 動かしてみないと間違いに気づかない(ClassCastException)
 ドキュメントなどで型を明示
Java1.5からはジェネリクスを使えるようになった
 ダウンキャストが不要
 コンパイル時点で型の間違いに気づく
 必修事項が増えました

今日のキーワード:Generics Hell

入門編
スコープ
 ・メソッドの中でのみ有効なジェネリクス
 ・インスタンスの中でのみ有効なジェネリクス
ジェネリクスメソッド
 ・メソッドのin outの型の関係性を表す
 ・java.util.Collections.shuffle(List list)はジェネリックメソッドではない(戻り値が無いから型の関係性が無い)
ジェネリックメソッドの呼び出し方
 Collections.replaceAll(list, “hoge”, “piyo”);
 普通は書かなくても、型推論してくれる
ジェネリックインスタンス
 ・複数のメソッド間のin outの型の関係性を表す
3種類の<>
 ・型変数の宣言
 ・型変数のバインド
 ・パラメータ化された型
型のバインド
 ・仮型引数と実型引数は、メソッドの仮引数と実引数の関係性と同じ
ダイヤモンド演算子
推論器
 Java7では推論が弱いが、Java8ではラムダのために強化された
 戻り値がある型だから、引数はこの型だろう、というのはJava7では推論出来なかった
継承によるバインド
 public class StringList extends ArrayList { … }
 Map>> とかやらずに、適度なレベルで継承したクラスを作ったほうがわかりやすくなる
 クラスを作るのをサボらない
パラメータ化された型の代入互換性
 配列でやると、ArrayStoreException が発生
  B arrayB = new B[1];
  A arrayA = arrayB;
  arrayA[0] = new B();
 ジェネリクスでやると、コンパイルエラー
 Bの集合はAの集合の代理をできない(集合論的に)
 ワイルドカードの使用
  ArrayList とか、ArrayListとか
  ArrayList は add()ができない
  ArrayList は getの戻り値がObjectになる
まとめ
 まずはきれいなオブジェクト指向の設計を
 3種類の<>を意識する
 代入互換性は訓練あるのみ

困ったら @Nagise さんへ。

中級編
型変数の境界
 class Hoge
 境界を定義できる
 &でインターフェースを境界に加えることが出来る(Object & Serializable)
再帰ジェネリクス
 abstract class Hoge> {
 newでバインド出来ない
 継承で扱う class Piyo extends Hoge
 自分自身のクラスを返す・引数にするメソッドを宣言できる
 java.lang.Enum の compareTo とかで使われている
内部クラスのジェネリクス
 内部クラスは外部クラスの型変数を利用できる
 Outer outer = new Outer();
 Outer.Inner inner = outer.new Inner();
 Iterator とかで利用している
リフレクション
 イレイジャ方式
 パラメタライズド・タイプの型情報は欠落しない
 java.lang.reflect.Type(マーカinterface)を返すメソッドから、ダウンキャストして使う

上級編
コンストラクタの引数の形は継承で制約できません→Factoryで実装
継承によるバインドであれば、型情報から型変数に何がバインドされたかを知ることが出来る getGenericSuperclass
template methodパターン
まとめ
 new T()したくなるシチュエーションには継承によるバインド+リフレクションを使えないか検討する

ネタ
 型変数の相互利用
 型変数の部分適用(高階型変数)




・テンプレートエンジンと。。。
テンプレートエンジン導入前の現場
 デザイナーが作っていたHTMLをプログラマJSPに移植していた
 工数が高い、開発スピードが遅い・つまらない作業
→デザイナーが直接テンプレートを書ければ良い
Mayaa
 単体で利用可能()
 採用した理由
  JSPをそのまま置き換えられる
  日本人が作っているので日本語ドキュメントが充実
  2005年ぐらいからあるので実績がある
 工夫したこと
  m:idの命名規則が重要
   4種類
    IF_xxxx
    LOOP_xxxx
    xxxx_HERE
    xxxx_TAG
  共通部品:サーバサイドincludeの再現
   サーバ側でincludeすると、ヘッダ・フッタなどの全体を見ながらできない
   iframeを使って擬似的に再現
    javascriptを使って高さなどを調整
    chromeセキュリティポリシーに引っかかる。Firefoxを使えば動く
  m:id一覧表を自動作成
   MayaaファイルはXML形式→SAXでパース→Mayaaを使ってHTMLに変換
   JavaDoc風に各
  相対パス自動調整機能を徹底活用
   PathAdjusterを活用
   相対パス絶対パスに変換だけでなく、https・パスの追加・クエリ文字の追加など
  属性をパラメータとして使用する→m:idが多くなりすぎることを防ぐ
   標準では実装されていない
  Mayaaファイルを毎回コピペしないで済むようにする
   mayaaファイルを少しだけ追加したい
   ProviderUtil.getParentSpecificationResolver().getParentSpecification(spec)を書き換える

デザイナー目線
 とにかく命名規則とドキュメントが命!!
 機能が多くなればなるほど名称や動きは複雑に!
 WordPressがデザイナーに人気なのは、ドキュメントが豊富であったり、検索で出てくるから
  →ドキュメントはちゃんと書きましょう

よくある事例
 プログラマ・デザイナの得意分野は違うので、それを理解することが大事
 プログラマに必要なスキル
  問題を切り分ける能力
  HTML/CSSとかは当然使えなければいけないスキル
 デザイナに必要なスキル
  最終的にプロダクトを制作しているという責任感
   プログラマの判断をアテにしない(ぐらいの勢い)
 行ったほうが良い取り組み
  デザイナのPCに開発環境をインストールさせない
  問題が起こったら毎回フォローしなければいけない
  試験環境を用意する
 勝手なことをしない
 お互いの分野を理解する


・ユニットテスト改善ガイド
ユニットテストにまつわる10のかんちがい
本:実践アジャイルテスト

ユニットテストの書き方がわかりません
 →テスティングフレームワークやテスト手法を学ぶ
 ユニットテストは簡単ではない
 ヒント
  学ぶ機会を作ろう
  トレーニングを行う
   プロジェクトのコストとして扱わない
   可能な限り、業務時間で行う
  ティーチング可能な経験者を探そう
  JUnit実践入門がおすすめ
どこからユニットテストを始めたらよいかわかりません
 →まずはユーティリティクラス・メソッドから始める
 簡単なところから始める
 テストしやすいクラス
  入力に対して出力が一定である
  状態を持たない
 複雑な条件式は抽出したら、テスト可能
ヒント
 経験を積み重ね、範囲を広くしていく

対象のコードがテストしにくいです
 →テストしやすく修正するチャンスです
 テスト対象は修正しても良い
 ヒント
  可読性の高いAPIはテストしやすい
   リファクタリングを学ぶ
  テストファーストを学ぶ
   プロジェクトで矯正する必要はない
   状況によって使い分ける

CIを導入したいです。
 →効果的ですが、先にテスト文化を作るほうが大切です
 CIだけあってもテストがダメでは効果が薄い
 自分の時間を使い習得し導入するしかない
 ヒント
  はじめにテストする文化を作ること
  何時でも使えるようにCIを学んでおく
   ローカルでとりあえずやってみるのもOK
   AWSに構築するのもOK
   古いマシンでもOK

テストコードのメンテナンスが大変です。
 →テストコードを定期的にリファクタリングしてください
 ユニットテストはプロセス
  継続して行うことで効果が高くなる
  単発プロジェクトには適さない(ペイ出来ない可能性が高い)
 テストコードのメンテナンス
  プロダクションコード以上に冗長化する
  最初から不リファクタリングしながらテストコードを書いていく
 開発時のコスト
  プロダクションコードのプログラミング+テストコードのプログラミング+テストコードのリファクタリング
 ヒント
  フィクスチャの外部化
  RuleやカスタムMatcherの作成
  共通処理の抽出
  フレームワークの独自拡張

他のメンバーがユニットテストに興味がありません
 →便利なデバッグツールとして広めていきましょう
 ユニットテストは矯正してはいけない
 効果や目的を説明する
 自発的にやってもらう
 printfデバッグ→テストコード に置き換える
 単体テスト(Excelなど)の置き換えとして導入する
 ヒント
  メンバーの手間を増やさないこと
  必ず、導入する目的を説明する
  仲間を増やす(日本人は周りに流されやすい。少人数なら一人でも作れば周りが流れてくれる)
  既存の作業を置き換える形で導入する

上司を説得できません
 →品質向上はNG、教育(スキル向上)のため
 テストの分類
  ・製品を批評するテスト
  ・チームを支援するテスト
 ヒント
  導入の目的は教育的効果
  リグレッション防止もOK

随分前から失敗のままのテストコードが残っています
 →直ぐに修正します。出来そうにないならば捨てましょう。
 テストコードをリファクタリングしましょう
 整理し過ぎるとテストとしての可読性低下
 難しいが工夫が必要で楽しいところ
 ヒント
  保守コストにテストコードの保守も含める

納品物としてテスト仕様書などが求められています
 →可能な限り省エネで作りましょう
 納得されなそうな場合は最終結果のみ報告
 レポートでページ数を稼ぐ
  JavaDocの印刷
  カバレッジツールのレポート機能(%の説明が必須)
 成果物作成が重荷になる場合
  なんとか説得
  併用
  ユニットテストを諦める
  いろいろ諦める
 ヒント
  指標として、テスト件数やカバレッジは有効

テスト対象のコードを変更できない
 →次に期待しましょう
 個人では買えられない壁は存在する
  見方を多くつくる
  変化を促進できるポジションにつく
 ヒント
  頑張らない
  常に「どうすればテストしやすいか?」を考え、次のプロジェクトに生かす

レガシーコードが相手です
 →勝ち目がないテストはやめましょう
 ヒント
  テストできないからレガシーコード

リソースが足りません
 →導入してはいけません
 導入して失敗すると、そのせいにされ、以降の導入が難しくなる
 ヒント
  余裕があるときにやる






アプリケーションサーバ特性
 ・長時間の実行
 ・複数ユーザからの同時アクセス
 ・アプリとインフラの中間
ログ管理
 トラブルシューティングの基本
 GCログ
  GCチューニング、メモリリークやOutOfMemoryError分析に必要
  -verbose:gc:基本
  printgcdatestamps
  printgcdetails
  ログローテーション
  GCViewer
  上書きに注意
   再起動前に堆肥 or -Xloggc:gc-`date …`.log
  OSコマンドでの矯正ローテーションは大抵正常動作しない
  GC統計
   jstatは統計情報としては役に立つが、障害解析にはあまり役に立たない
  ヒープの詳細な解析
   ヒープダンプは最低2回取得して、差分を解析
   OOME発生時にダンプする設定をしておく
    OOME発生後はJVMとしての動作が保証されていないので、必ず再起動
 標準出力・エラー出力ログ
  sysout, syserrはダメ
 スレッドダンプの解析:ThreadLogic
 ログのローテーション
  Apache付属のrotatelogsなどの利用
   java 〜 2>&1 | rotatelogs -l console.log.%Y%m%d 86400
   ログの削除も別途見当
  > /dev/null はダメ
 アクセスログ
  とりあえず有効化
  Webサーバ・アプリケーションサーバどちら側の問題かを判断
  レスポンス時間も取得
  セキュリティ・監査目的でも
 サーバログ
  通常INFO以上にすべき
監視・統計
 OS関連
  CPU:使用率、キュー長
  メモリ:使用料、ページング
  ネットワーク:ソケット状況、I/O発生量
  vmstatを利用
  スレッドごとのCPU使用率が重要
 ログ
  ERRORレベル以上を基本的には監視
  GCログやアクセスログから統計
 死活監視、リソース監視
  死活監視
   実際にリクエストを投げて応答を確認
   Full GCを考慮してタイムアウトやリトライを実装
  MBeanによるリソース監視・統計:Java Mission Controll
チューニング
 アプリケーション/アプリケーションサーバ/JVM/OS/HardWare
 サーバ分割・分散配置
  計画的に再起動することで、リーク解消にもなる
 OS環境設定
  ファイルディスクリプタ(目安:8192、ただしWebSocketの場合は足りないかも)
  コアファイルサイズ
 ネットワーク関連設定
  TCP
   connectのタイムアウト、KeepAlive、TIME_WAITのタイムアウト
  接続バックログ
  IPv4を有線
 JVMメモリ・GCのチューニング
  ヒープサイズ
   Xms = XmXにしましょう
   大きい場合、GC回数は減るが、GC時間が上がる
  GC方式
   レスポンス重視
   スループット重視
 スレッドのチューニング
  スレッド数はTPS * レスポンス時間
  リクエストキュー長も制限
 コネクションプールのチューニング
  基本は、初期容量=最大容量、スレッド数 >= 容量
 タイムアウトのチューニング
  実行タイムアウトを直接的に指定できない
まとめ
 古いバージョンを利用している方は、アプリケーションサーバだけでもバージョンアップを
 アプリケーションサーバ特性をしる
  



従来型
 Server side scripting
次世代型
 single page application
がサーバ屋視点

フロント屋視点で
1. Tools
2. Architecture
3.Formats

tool
 とにかくたくさんある
 フロントエンド開発ツールの組み合わせ
  ASP.NET+OOS Visual Studio
  SenchaSDK
  ベンダ系のツールの整合性が非常に高い
  オープン系(Eclipse)はばらばら(つらいが、新しいものを組み合わせられる)
 サーバの開発ツール
  IDEのプラグイン拡張で
 フロントエンドの開発ツール
  エディタは別で、ツールは黒い画面で
  プラグインを通さない
 バックグラウンド処理のデファクトはGrunt
  (Grunt知らない人もけっこういる)
 サーバとフロントが独自の道に走っている
architecture
 5年前の主な議論はいかにつなげるか、だった
 ここ数年でレイヤーが上がった
 つなぐことはあたりまえ
 いかにしてモジュール間通信を行うか
  ASP.NET(SignalR
   RPC
  Sencha(CommonJS) + NodeJS
  Java(JAX-RS) + Backbone.js(sync) が鉄板っぽい
   RESTの思想でインターフェース設計
   クライアント・サーバ間でリソース同期
 Project Avator
 jQueryの恐怖
  WebデザイナのjQuery=CSSの延長
  業務やサンのjQuery=業務ロジック
   フレームワーク無しで業務コードを書き始める
  実は結構、揺れている時期なのかもしれない
formats
 SPAの理想的な協業
 pjax
  欠点:クロスブラウザ対応できない
   検索に弱かったりする
  欠点:初期表示に時間が掛かる
 デザイナ<=>プログラマのジレンマは続く
エンタープライズ分野ではWeb技術は敬遠されている
 Javaも昔はそうだった
 Javascriptの性能も上がった


メンテナンス性の良いWebシステムを構築するために

最近、フロントの実装料が増えてきた
サーバ・JSで同じものを実装することになってきた

1. 画面構築方式
 Ajax登場以来、画面構築方式が複雑化
 従来:サーバでHTMLを生成
 新方式:フロント側でもMV*系のフレームワークを導入
  サーバはRESTのインターフェース
 混ぜると危険
 DOM操作・Ajaxに加え、テンプレート・リソース同期・JSの構造化
  JAX-RSなら大丈夫
 JSFが多くをやりすぎる(役割分担が難しい)
3.
 JAX-RS
  サーバはRESTインターフェースのみ
  画面はフロント側で生成
  Backbone.js, Anguler.js と組み合わせやすい
  注意点
   フロント側の実装料は増える
   テンプレートエンジンが必要
   初期表示時に余計なリクエストが飛ぶ
 JSF
  画面はサーバが作る
  Ajax通信時もサーバ側で画面を作る
  Ajaxでの画面部分構築はを利用する
  JSFAjaxXML形式で独自色が強い

Adobe Media Server 5 Starter でサーバに f4v 形式で保存する

技術検証のために、やってみた。

構成

インストール

両ソフト共に無料だけど、Adobe IDは必要な模様。 本当はCentOS用のファイルを落として、VirtualBoxでインストールしようと思ったけど、なぜかダウンロード出来ず。。。

Adobe ID取得のためには会社名とかいろいろ入れないといけないみたいだけど、"individual"とかてきとーに書いておいても通った。

Serverのインストールは、ダウンロードしたファイルを解凍し、「windows/AdobeMediaServer_5_LS1_win64.exe」を実行。

サーバの設定

普通にインストールした場合、「C:\Program Files\Adobe\Adobe Media Server 5」にもろもろのファイルが入ってます。

  • samples/applications/livepkgr を、 applications 以下に hoge というフォルダ名にコピー
  • main.asc の98行目の Stream.get の引数を "mp4:" + streamObj.name + ".f4v" に変更

クライアントの設定

  • Flash Media Live Encoder を起動
  • 下記を設定
    • FMS URL : rtmp://192.168.81.2/hoge
    • Stream : livestream?adbe-record-mode=record&adbe-live-event=liveevent
  • 「Start」ボタンを押す

これにより、 hoge/streams/_definst_/livestream.f4v が作成されるので、てきとーなところで「Stop」ボタンを押す。

クライアントから再生してみる

  • サーバ:作成された livestream.f4vapplications/vod/media/hoge/ にコピー
  • サーバ: samples/videoPlayerwebroot 以下にコピー
  • クライアント:ブラウザにて http://192.168.81.2/videoPlayer/videoplayer.html にアクセス
  • STREAM URL:rtmp://192.168.81.2/vod/mp4:hoge/livestream.f4v を入力し、「PLAY STREAM」を押す

その他

以下、未確認。

手動でコピーするのもアレなので、スクリプトを変更する必要がある。
hogeアプリケーションが他のディレクトリを操作できるように、 Application.xml を操作する必要がある。

<FileObject> 
    <VirtualDirectory>/vod;C:\Program Files\Adobe\Adobe Media Server 5\applications\vod</VirtualDirectory> 
</FileObject>

main.asc の111行目で onStatus を定義しているので、そこで info.code == "NetStream.Record.Stop" の場合にファイルの移動を実行する。
ファイルオブジェクトは new File("/streams/_definst_/livestream.f4v") で作成可能。
File.renameTo()/vod/media/hoge/livestream.f4v に移動。

参考リンクなど

退プロしました。

退職しましたエントリがあるのなら、退プロしましたエントリがあってもいいんじゃないか、ということで書いてみる。
プロジェクト在籍期間は1年半でした。

前提

4年間勤めた富山のSIerを2012/3に退職。
SIerでは3次請けやら4次請けやらのプロジェクトに、プログラマとしてアサインされることが多く、 Javaでのコーディングはできるけど、設計ナニソレ状態でした。

ジョブチェンジ&プロジェクトに参画

2012/4 にモンスター・ラボの社員に。
その日からこのプロジェクトに参画しました。
最初の説明としては、「FacebookみたいなSNSで、写真を投稿するサービス」ぐらいの説明で、なんとなく理解できてしまったのが、B2Bとは違うところだなーと感じました。
B2Bの案件で、「N社の債権債務システムみたいな感じで・・・」とか言われても、そのシステム見たこと無いしーってなりますし。

技術的なこと

4年間サーバサイドJavaオンリーで仕事してきたところへ、言語的には

のプロジェクトに入り、「Javaだとこのクラスを使えるけど、PHPのそれに対応したものはどれだー」状態で、
そこへきて、「Redis使って更新通知を作ってみて」・・・って、Redisってなんじゃー状態になりながら、
知らなかったことをたくさん吸収できたかとは思います。(成果も"それなり"には上げたと思ってます)

そして常駐へ

1,2ヶ月たった頃から、お客さんの方で内製化の機運が高まり、7月の中旬に客先常駐となることになりました。
自社からは自分含め3名で。
直後はまだ受託の契約で、口頭で「ここはこんな風にできません?」みたいなのに、どこまで対応してよいのやら、難しかったです。(そもそも時間がないから無理、ってことも多かったですが。。。)
で、8月の後半リリースに向け、十数名の体制になり、楽ができるかと思いきや、質問やら修正依頼やらが自分に集中してしまい、当時は自分でもよくやってたと思います。(被害妄想?+自画自賛。。。

ちなみに、常駐前は週休1日制でしたが、週休2日制にグレードアップしました。

リリース、そして最後の一人

無事リリースを終えたものの、
バグだーと言われれば直し、
機能追加だーと言われれば追加し、
認証基盤様からの要求じゃーと言われればそれを実装し、
キャンペーンを始めるぞーと言われればそのページやら仕組みやらを実装しました。
そうこうしている間に、自社から行っていた人は、退職やら、別プロジェクトへ異動やらで、一人になりました。
それから1年ぐらいは、自社に帰るのは月1回、自社の人たちに会うのもそのタイミングぐらいって日々でした。
自分はどこの社員なんだろう・・・?って思うこともありましたが、前の会社でも似たような事があったので慣れてました。

人の入れ替わり、受託時代の負の遺産

月日が経つと、それぞれの事情によりプロジェクトを異動だったり、契約が終わったりで、人が抜けて行きました。
ただ、会社としても期待されていたプロジェクトらしく、抜けた分ぐらいの人は追加で入ってきました。
その頃ぐらいから言われてたのが、
なんじゃこのコードはーとか
このアーキテクチャはおかしいーとか
でした。
ここらへんに関しては、自分もそのころには感じておりましたが、初期の製造段階での質もあまりよくなく、
その負債を回収する暇もなく進んでいました。
プロジェクトメンバーも悪い人はおらず、直接自分が糾弾されることは無かったのですが、精神的には地味にきつかったですね。

書き直し

そんな経緯もあり、コードを描き直そうという動きがあったのですが、直近のタスクが溜まっていたり、人の入れ替わりによりスキルセットが変わってしまったりもあり、なかなか進みませんでした。
それが、なんやかんやあり、2013/7 ぐらいから、サーバ側はRuby on Railsで書き直すことに決定しました。
で、同時にデザイン・マークアップ・JS・iOSネイティブ・Androidネイティブ の全てを書き直すことにもなりました。
そのため、自分だけが知っていたことなども、他の人に引き継ぎやすく、タイミングとしてはよかったと思います。

メインはRubyでの書き換えをやりながら、ちょっとは運用系のタスクでPHPを修正し、家に帰ったらPythonやらObjective-Cをやる、という混乱は引き起こされましたが。。。

退プロ

途中の予定では、退プロするまでにALL書き直ししたものがリリースされる予定だったのですが、いろいろあって、リリースされる前に抜けてしまうことになりました。
ここに関しては、すこし残念でした。
機会があれば、完成形がどうなったかは知りたいです。

まとめ

  • PHPの経験が1年3ヶ月増えた!
  • iOSの経験が2ヶ月(ぐらい)増えた!
  • Java(Android)の経験が2ヶ月(ぐらい)増えた!
  • Ruby on Railsの経験が3ヶ月増えた!
  • Redisの経験が増えた!
  • MySQLの経験が増えた!
  • RabbitMQの経験が増えた!

ただし、本番のインフラはさわれなかったので、その辺のスキルはまだまだだと思います。。。

ということで、外部記憶の意味も込めて、書き殴ってみました。
NDA的にとか、問題ありそうなら即刻消しますので、ご連絡ください。

iOSのPUSH通知実装を行う(iOSネイティブその1)

前回はPush Notificationの有効化と、証明書の作成を行ったので、今回はiOS側のコーディングを行います。

基本的なことは、Appleの公式ドキュメント を見ましょう。
リスト 2-3あたりです。

今回の差分はこのへんです。

手順

まず、どのようなPUSH通知を利用するかを指定し、登録プロセスの開始を依頼します。
コードとしては、AppDelegateの application:didFinishLaunchingWithOptions: にて、 registerForRemoteNotificationTypes: を実行します。
今回は、バッジ(Home画面のアプリアイコンに数字を付ける)・サウンド・アラート(文字列を表示する)の全てを指定しています。
不要なものがあれば、省くべきかと思います。(あとで、やっぱり必要になった。とかが無いのであれば)

    // PUSH通知の設定
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge|
                                                                            UIRemoteNotificationTypeSound|
                                                                            UIRemoteNotificationTypeAlert)];

次に、デバイストークンを取得するために application:didRegisterForRemoteNotificationsWithDeviceToken: を実装します。

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    NSMutableString *tokenId = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"%@",devToken]];
    // TODO 変換が必要?
    NSLog(@"deviceToken: %@", tokenId);
}

引数で与えられた、 devToken がデバイストークンと呼ばれているものです。
ただし、NSData * 型で与えられるので、サーバに送信する際などには文字列とした方が便利だと思います。
今回は一旦、NSMutableString * 型に変換して、ログ出力を行います。

しかし、エラー

application:didRegisterForRemoteNotificationsWithDeviceToken: メソッドが実行されず、

Errorinregistration:Error Domain=NSCocoaErrorDomain Code=3000 "Appの有効な“aps-environment”エンタイトルメント文字列が見つかりません" UserInfo=0x17daec40 {NSLocalizedDescription=Appの有効な“aps-environment”エンタイトルメント文字列が見つかりません}

がログに出力されました。
このサイト が見つかったので、プロビジョニングプロファイルを再生成することにしました。

おそらく、Xcode上で「Fix issue」を押してしまった後に、Identifier?を変更したためだと思われます。
順番が違っていたら、不要な手順かも。

プロビジョニングプロファイルの生成手順

iOS Dev Centerから、「Certificates, Identifiers & Profiles」を選択し、「Provisioning Profiles」を選択しました。
下記の画面で、「+」のアイコンをクリックします。

f:id:suzaku114:20131001021431p:plain

今回は開発用のプロビジョニングプロファイルを作成するので、「Development」の「iOS App Development」を選択します。 「Continue」をクリックします。

f:id:suzaku114:20131001021424p:plain

作成対象としたいApp IDを選択し、「Continue」をクリックします。

f:id:suzaku114:20131001021417p:plain

含めたい証明書を選択し、「Continue」をクリックします。

f:id:suzaku114:20131001021411p:plain

含めたい端末を選択し、「Continue」をクリックします。
(端末が増えると、ここもやり直しになってしまうのが、めんどいところですね)

f:id:suzaku114:20131001021404p:plain

このプロファイルの名前を入力します。
今回は、Development用なので、末尾に「Development」を付けました。
「Generate」をクリックします。

f:id:suzaku114:20131001021356p:plain

プロビジョニングプロファイルが作成されましたので、「Download」をクリックします。 ダウンロードが完了したら、「Done」をクリックします。

f:id:suzaku114:20131001022422p:plain

「プロファイルの名前.mobileprovision」をダブルクリックすると、Xcodeに設定されます。
あとは、プロジェクトの「Build Settings」の「Code Signing」の「Provisioning Profile」を「プロファイルの名前」に変更します。

f:id:suzaku114:20131001021342p:plain

この状態で、再度実機で実行すると、アラートが表示され、ログにデバイストークンが表示されました。
ただし、

deviceToken: という形で表示されるので、"<", ">", " "の文字が余計なような気がします。
他の人のコードを見ていると、省いているようですが、そこら辺はまた今度やろうと思います。