JVM終了時に何かする
https://github.com/playframework/play/commit/eca4a6b06cef4e591a24c3fa7c67001b15fec6aa
Play! frameworkのパッチを読んでて気づいた。
java.lang.Runtime#addShutdownHook(Thread)を使うと、現在起動しているJVMの終了時に好きなスレッドを実行できるみたい。
アプリケーションがCtrl+cなど意図しないタイミングで終了された場合に後始末をするような場合に使えそう。
scala> Runtime.getRuntime.addShutdownHook(new Thread { override def run { println("shutdown hooked!") } }) [ここでCtrl+cを押す] scala> shutdown hooked!
2010年のmumoshuまとめ(転職)
小規模でしたがAndroidアプリ開発の案件も軌道にのってきてリリースがみえてきた4月頃に、いわゆる企画部のような部署に異動になりました。
異動そのものは良かった。もともと、企画と開発の人間の席が並んでないとWebサービス開発なんてできないという思いは強く持っていたので。
ただ、異動によって、Androidアプリ開発から手を引くことになったのが非常にもったいなかった。
PC向けサイト開発に大きな不満があったわけではないですけど、別のワクワク感が欲しかった。Androidアプリ開発はそれにうってつけだったのですが・・。
そんな状況で、5月に大学時代の友人と飲み会をして、今勤めてる会社を紹介してもらいました。
小規模ながらも、エンタメ系の事業を幅広くやっていて、ケータイサイトもつくっている、また、開発は内製でやっているらしい。
元々、敏腕プログラマー(w)がたくさん居るような会社、自分が(実装の)実力的に下の方に位置づけられるような職場で働いてみたいと思っていたし、ケータイサイト開発という自分がまだやったことのない新しい分野の開発に求めていたワクワクを感じた。
とりあえず、そこの開発部長さんを紹介してもらってtwitter上でお話をさせてもらった。
率直に面白そうだと思ったので、採用試験を受けて、6月頃には内定が出た。
内定が出た後はすぐ、9月頃に転職のため退職する旨をその時の上司に連絡。
「ちょっと遅すぎる」と言われたが仕方ない。
転職先からは早く入社して欲しいといわれるし、元の会社からはもっと期間に余裕を持たせてほしいと言われるし、板挟み。
残りの三ヶ月は、とりかかってた案件を必死にやってたらすぐだった。
引継ぎについては、実装のできる社員がいなかったので、実装周りのお仕事は全部、超できる派遣さん(Java使い)に。
退職する直前になって、色んな人から追い出し飲みに誘っていただいて嬉しかったー。
色々あったけど、退職当時も今も、前の職場で働けたことはプラスだなと思っています。
感謝。
2010年のmumoshuまとめ(内製はじめた)
ちょっと自分語りしますが、2010年は自分にとって色々と転機になる出来事が多かったですね。
2009年までは某ISPの開発部で開発管理の仕事をやってました。入社が2008年4月なので1年半以上ずっと、です。これがやはり自分には楽しくなくて、モチベーションが上がらなかった。
仕事をこなす中でスキル・マインド面で自立したエンジニアになれるか、というのが自分が仕事を選ぶ重要なポイントなのですが、開発管理だけやっててもそうはならないなーと悟ってしまったんですね。
プログラミングスキルなんかその最たるもので、当然仕事ではプログラミングする時間とれなかったので学生時代から全然上達しない。学生時代の知識を切り崩しながら仕事をこなす感覚が日々強くなってました。
システム開発やってて、インフラもアプリも監督しなきゃいけないのにこれじゃいかん、ということで上司に無理を言って担当してた案件をひとりで内製させてもらことにしました。それが軌道にのったのが2010年の1月頃。
それから何個か内製案件をこなしつつ、社内のAndroidアプリ開発にも絡んでいきました。Androidが流行り始めたので会社としても力を入れていこうという話になっていて、そこにうまく入り込めた感じですね。趣味で少しAndroid SDKを触りつつ習作アプリを作ったりしていたのが功を奏しました。
その頃は内製案件も兼任していた状態だったので、人手が足りないだろうということで派遣さんにひとり来ていただいたり。僕にとっては初めての対等な立場の開発パートナーで、色々いい経験をさせてもらいました。というか、その方のスキルの高さに毎日驚くばかりでした。
「これがプログラマーか!」って感じでしたね。
つづく
あけましておめでとうございました
今年もよろしくお願いします。
Play+ScalaによるGAEアプリの開発方法について
(この記事は Scala Advent Calendar jp 2010 の6日目です。)
Play! + Scala + GAEのWebアプリ開発はどんなものか調べてみよう…とおもったら、
既に@ymnkさんがplay+scala+gaeのサンプルアプリGitHub - ymnk/lists-with-play-scala-gae: A sample program for Play! Scala with GAEを作られていました。
このサンプルは、
- Play! Framework(Java用のWebアプリケーションフレームワーク)
- Play!用のScalaモジュール(MVCがJavaでは無くScalaで書けるようになります)
- Play!用のSienaモジュール(GAEに対応しているSienaというORMapperをPlay!から使えるようにするモジュールです。Play!のModelはGAEに対応していないため。)
- Play!用のGAEモジュール(Play!アプリを殆ど変更せずにGAEにデプロイできてしまう夢のようなモジュール)
を使って作られていて、GAEにデプロイすればそのまま動きます!
これから始める方は、このサンプルをベースに始めると良いと思います。
素晴らしいサンプルアプリをありがとうございます!>@ymnkさん
と、これだけではアレなので、今から始める方向けにplay+scala+gaeによる開発環境の構築からGAEへのデプロイまでの手順を、またガッツり実アプリを組む方向けにFunctionalTestの書き方を残しておきます。
環境構築〜サンプルアプリの実行とGAEへのデプロイ手順
- Play Framework - Build Modern & Scalable Web Apps with Java and Scalaとscalaのインストール。playとscalaにはパスを通しておいてください。
- play install scala
- play install gae
- play install siena
- http://code.google.com/intl/ja/appengine/docs/java/gettingstarted/installing.htmlに沿ってappengine-java-sdk-1.4.0をインストール。GAE_PATHを設定するのをお忘れなく。
- https://appengine.google.com/ でappengineへの登録とアプリケーションIDの払い出しをする
- git clone git://github.com/ymnk/lists-with-play-scala-gae.git
- war/WEB-INF/appengine-web.xmlにappengineのアプリケーションIDを書く
- ローカルで動かしてみる
play run
http://localhost:9000/にアクセスすると、appengineのdev_server上でPlay!アプリが動いています。
- playコマンドからデプロイ
play gae:deploy
http://アプリID.appspot.comにアクセスすると、Play!アプリがGAEアプリ上で動いています(!)
FunctionalTest
Play!のView & Controller、SienaのModel、GAEの開発環境(認証とDataStore)を通したファンクションテストを書いてみます。
ポイントは、
- GAEのテスト用DataStoreとユーザ認証のセットアップ。これにより、テストケース上で、DataStoreにアクセスしたり、googleのユーザ認証を前提としたコードをテストできます。
- Siena用のFixtureクラスがないので、テストのsetUp時にテストデータをテスト用DataStoreにinsert
- FunSuite + ShouldMatchers + Play!提供のテストメソッドの組み合わせ。見慣れたscalatestでPlay!アプリのテストが書けます。
です。
コード
import com.google.appengine.tools.development.testing.{LocalDatastoreServiceTestConfig, LocalUserServiceTestConfig, LocalServiceTestHelper} import org.junit._ import org.scalatest.matchers.ShouldMatchers import org.scalatest.{FunSuite, BeforeAndAfterEach} import play.test._ import play.mvc._ import play.mvc.Http._ import models._ import collection.JavaConversions._ class ListsTest extends FunctionalTest with FunSuite with ShouldMatchers with BeforeAndAfterEach with Browser { /** * this emulates user login * see: http://code.google.com/intl/ja/appengine/docs/java/tools/localunittesting.html#Writing_Authentication_Tests */ private val helper: LocalServiceTestHelper = new LocalServiceTestHelper(new LocalUserServiceTestConfig(), new LocalDatastoreServiceTestConfig()) .setEnvIsAdmin(true).setEnvEmail("foo@bar.com").setEnvAuthDomain("http://localhost") /** * I didn't really want to write <code>getContent(response) should be ("contentExpected")</code>... */ implicit def makeResponseRicher(response: Response) = RichResponse(response) case class RichResponse(response: Response) { def content: String = getContent(response) } override def beforeEach() { helper.setEnvIsLoggedIn(false) setUpLocalServices } override def afterEach() { helper.tearDown clearCookies } private def setUpLocalServices { helper.setUp val userEmail = "foo@bar.com" val exampleList = new List(userEmail, "exampleList") val exampleItem = new Item(exampleList, "exampleItem") exampleList.insert exampleItem.insert } private def withLoggedIn[T](tests: => T) { helper.tearDown helper.setEnvIsLoggedIn(true) setUpLocalServices tests } test("Lists.index when logged in") { withLoggedIn { val response = GET("/lists") response.status should be (200) response.content should include ("exampleList") } } test("Lists.index when not logged in") { val response = GET("/lists") response.status should be (302) } test("Lists.show") { withLoggedIn { val exampleList = ListOp.all.fetch().get(0) val response = GET(newRequest, "/lists/" + exampleList.id) response.content should include ("exampleItem") } } }
テスト実行方法
play test
を実行して、http://localhost:9000/@testsにアクセスして、ListsTestを選択し"Run tests"をクリック
@ymnkさんのサンプルに上記FunctionTestを追加して、GAEモジュールのバージョンを上げたものをGitHubに上げておきます。
https://github.com/mumoshu/lists-with-play-scala-gae
mvn cargo:deployが失敗する(com.sun:tools:jar:1.4.2が見つけられない)
$ mvn cargo:deploy
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building t3
[INFO] task-segment: [cargo:deploy]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.Missing:
- -
1) com.sun:tools:jar:1.4.2
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=com.sun -DartifactId=tools -Dversion=1.
4.2 -Dpackaging=jar -Dfile=/path/to/fileAlternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=com.sun -DartifactId=tools -Dversion=1.4.
2 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
pom.xmlに以下を追記すればOK.
default-tools.jar
true
java.vendor
Sun Microsystems Inc.
com.sun
tools
1.4.2
system
${java.home}/../lib/tools.jara
専門書買取ネットつかってみた
技術書・ビジネス書をダンボールにつめて集荷してもらって送付。
22冊で2600円也。
あんまり汚れてた記憶はないけど、新品同然だったらもっと高かったのかな。
ブックオフでコミック1冊70円くらいで買取してくれることを考えると安いけど、技術書ってコミックと比べると市場も小さいし、古いとあんまり使い道ないから、こんなもんか。
本査定結果は【2,600円】となりました。
全体の中にヨレ・スレ・ヨゴレのあるものが見られた為、誠に勝手ながらその分減額させていただいております。<中略>見積もり一覧
=========================================
WEB+DB PRESS Vol.45(ISBN:9784774134864)
WEB+DB PRESS Vol.53(ISBN:9784774140049)
WEB+DB PRESS Vol.51(ISBN:9784774138909)
WEB+DB PRESS Vol.50(ISBN:9784774138381)
WEB+DB PRESS Vol.49(ISBN:9784774137520)
受託開発の極意―変化はあなたから始まる。現場から学ぶ実践手法 (WEB+DB PRESS plusシリーズ)(ISBN:9784774134536)
RailsによるアジャイルWebアプリケーション開発 第2版(ISBN:9784274066962)
Ruby on RailsによるWebアプリケーション・スーパーサンプル(ISBN:9784797341881)
10日でおぼえる Ruby on Rails入門教室(ISBN:9784798114729)
CMS構築 成功の法則(ISBN:9784774130613)
Rails of Ruby on Rails ~Case of LOCUSANDWONDERS.COM~(ISBN:9784839922214)
Drupal Pro Book CMSカスタマイズ&デザインガイド(ISBN:9784844325277)
Google Androidアプリケーション開発入門 画面作成からデバイス制御まで――基本機能の全容(ISBN:9784822283902)
モダンPerl入門 (CodeZine BOOKS)(ISBN:9784798119175)
Rubyスクリプティングテクニック ―テスト駆動による日常業務処理術(ISBN:9784873113562)
Railsレシピブック 183の技(ISBN:9784797336627)
楽して、儲ける!―発想と差別化でローテクでも勝てる!未来工業・山田昭男の型破り経営論!(ISBN:9784806119814)
ネーミングの掟と極意 (エンジニア道場)(ISBN:9784798114330)
はじめての上流工程をやり抜くための本 (エンジニア道場)(ISBN:9784798114378)
エンジニアのためのWord再入門講座 美しくメンテナンス性の高い開発ドキュメントの作り方(ISBN:9784798117133)
はじめてのRuby on Rails 2 (I・O BOOKS)(ISBN:9784777513536)
図解 利益を生み出すビジネス手法と事例108(ISBN:9784861300950)
*記載のないものについては買取対象外となっております。
=========================================