「なぜ、システム開発は必ずモメるのか?」を読んだ
- 作者: 細川義洋
- 出版社/メーカー: 日本実業出版社
- 発売日: 2014/08/01
- メディア: Kindle版
- この商品を含むブログを見る
システム開発プロジェクトにおいて、実際に起きた裁判を元に発生するトラブルの事例やそれに対する対応の例を挙げている本。
ストーリー風に書かれているため読みやすい。
受託開発における契約の問題などを取り上げているため、 自社で開発しているところには当てはまらない部分もある。
ベンダは専門家としてユーザー側に情報共有を積極的に進めなければ、 不備があった場合にそれに対して契約書に記載がない場合でもベンダの責任と認められることもある。 このあたり裁判所は、契約書だけを見ないで実態をみて判断しているんだなと感じた。
プロジェクトを成功させる上で必要なのは、 ユーザーとベンダが双方協力しあうことが不可欠だと言っていてやっぱりそうだよなとなった。
システム開発の目的は単に発注側の依頼を完了させるのではなく システムを使う人にとって価値を提供するという、 作ったその先にある目的を達成することが大切なのだと言っていて、 これまで開発していてあまり考えてなかったなと思い反省。
プロジェクト開始から終了までに管理上の注意するべきポイントが挙げられていて、 当たり前のことなのかもしれないけどマネジメント経験がないのでとても参考になった。
PlayFramework-2.4
Playframework 2.4
にアップデートしたところ、activator new
で作成したプロジェクトが、
IntelliJ IDEA
にSBTプロジェクトとしてimportできなくなったので、その対応をめも。
エラーの内容を一部抜粋
java.lang.UnsupportedClassVersionError: com/typesafe/config/ConfigException : Unsupported major.minor version 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ...skipping... at xsbt.boot.Boot$.main(Boot.scala:20) at xsbt.boot.Boot.main(Boot.scala) [error] java.lang.UnsupportedClassVersionError: com/typesafe/config/ConfigException : Unsupported major.minor version 52.0 [error] Use 'last' for the full log.
環境
$ java -version java version "1.8.0_51" Java(TM) SE Runtime Environment (build 1.8.0_51-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
Activator
activator-launch-1.3.6.jar
IntelliJ IDEA
14.1.4
IntelliJ IDEA: SBT (plugin)
1.7.0
IntelliJ IDEA: Scala (plugin)
1.5.2
以下の手順だと、エラーが発生する。
activator new ${PROJECT_NAME} play-java
activator new ${PROJECT_NAME} play-scala
以下の手順だと、エラーが発生しない
Java
activator new ${PROJECT_NAME} play-java-2.3
2.3.10のJava Project。 2.4系だと、エラーでるので諦めた。
Scala
activator new ${PROJECT_NAME} play-slick-quickstart
Slickという、ScalaのORMが入ってるやつ。
上記のコマンドは、プロジェクトテンプレートを利用して新規で作成している。
プロジェクトのテンプレートは、↓のページで一覧が見れる。
コマンドだと、↓
activator list-templates
Fetching the latest list of templates... Featured Seed Templates: minimal-akka-java-seed minimal-akka-scala-seed minimal-java minimal-scala play-java play-scala Featured Tutorial Templates: hello-akka hello-scala hello-slick-3.0 reactive-maps reactive-stocks Other Seed Templates: akka-http-adaptive-cluster-aws akka-scala-seed basic-project boilerplay ~ 省略 ~
SpringBoot入門
SpringBoot入門してみた
Spring Boot + Thymeleaf
環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.10.4 BuildVersion: 14E46
$ java -version java version "1.8.0_51" Java(TM) SE Runtime Environment (build 1.8.0_51-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
以下のページを参考にしましたm(__)m
- めちゃわかりやすい、チュートリアル記事2つ
- Spring Data JPAでの実装について
- Thymeleafの日本語ドキュメント
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.htmlwww.thymeleaf.org
- Spring MVCについて
個人でこれだけまとめるとかすごすぎ・・・
- Springをより詳しく知りたいときに読む
m12i.hatenablog.com http://terasolunaorg.github.io/guideline/5.0.1.RELEASE/ja/terasolunaorg.github.io
- 公式ドキュメント(英語)
- アプリケーションの設定値
http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.htmldocs.spring.io
- 書籍
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (5件) を見る
試しに、簡単なアプリケーションを作成してみた。
メモ. その1
Spring Securityで、どうやって認証が行われるのかよくわからなかった。
認証の設定は、SecurityConfig
でしている。
protected void configure(HttpSecurity http)
にて、アクセス認証の設定をしている。
public void configure(WebSecurity web)
では、セキュリティの設定対象外として設定している。
protected void configure(HttpSecurity http)
内でも、.antMatchers("/login/form").permitAll()
で同じようなことをしているが、 違いがわかっていない。。。
static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter
が、一番謎だった。
ざっくりと動作を記述する。
ログイン画面(/login/form)からFormが送信されると、
リクエストパラメータであるmail
の値がLoginUserDetailService#loadUserByUsername(String username)
に渡される。
この時、username
を元にリポジトリ(DB)から対象のデータ(レコード)を取得する。
取得結果が、nullならば存在しないユーザーIDなので例外をthrowする。
存在する場合は、org.springframework.security.core.userdetails.User
を継承した、LoginUserDetail
のインスタンスを返す。
LoginUserDetail
のコンストラクタには、引数として取得したAuthUser
のインスタンスを設定する。
LoginUserDetail
のコンストラクタ内では、org.springframework.security.core.userdetails.User
のコンストラクタを呼び出している。
呼び出しているコンストラクタの引数は、User(String username, String password, Collection<? extends GrantedAuthority> authorities)
となっている。
1, 2番目の引数は見ての通り、username
, password
になっている。
この値が、Formで送信された値と比較される。
パスワードは、SecurityConfig.AuthenticationConfiguration#init(AuthenticationManagerBuilder auth)
内で
設定したpasswordEncoder(getPasswordEncoder())
によって暗号化されて比較されるぽい。
Collection<? extends GrantedAuthority> authorities
については、
よくわかってないが認証したユーザーの権限を渡しているみたい。
わかったら追記。。。
LoginUserDetail
について
LoginUserDetail
は、org.springframework.security.core.userdetails.User
を継承したクラスorg.springframework.security.core.userdetails.User
は、org.springframework.security.core.userdetails.UserDetails
の実装なので、拡張(継承)して使うorg.springframework.security.core.userdetails.UserDetails
は、認証ユーザーの情報を取得するためのAPIを定義したinterface
メモ. その2
CSRFについて。
Spring Securityを有効にすると、デフォルトでCSRF対策が有効になるが、 Thymeleaf側で、正しくform要素を定義しないといけない。
以下のように、<form> ~ </form>
にth:action
属性を追加することで、
自動的に<input type="hidden" name="_csrf" value="e5521ea3-3cc5-4be4-84a5-7acd9ce10987" />
のような
トークンがリクエストパラメータとして追加される。
<form th:action="@{/xxx/xxx}" method="xxx"> ~ </form>
正しく設定されてない場合は、403でエラーとなる。
メモ. その3
Thymeleafでの、バリデーションエラーの表示について。
見たほうがわかりやすい。
<form th:object="${user}" th:action="@{/user/input}" method="POST"> ~ 省略 ~ <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">error</p> ~ 省略 ~ </form>
上記について。
th:if="${#fields.hasErrors('name')}"
user
オブジェクトのname
フィールドにエラーが存在するか
th:errors="*{name}"
name
フィールドのエラーを表示する
Thymeleafがオブジェクトのプロパティにアクセスする場合は、
getXxx
やisXxxx
のメソッドに対して、xxx
という名前に変換してアクセスするので、
アクセスするプロパティにはGetterが必要。
ex) user.name <- user.getName()
なので、Getterメソッドだけ定義してフィールドを宣言しなくてもOK。
ex)
sample.user.auth.domain.AuthUser#isCheckPassword
この辺の実装は↓
- sample.user.controller.UserController#confirm
- src/main/resources/templates/user/form.html
SpringBootを使ってみて
Springの面倒な設定がいらない。
Springのみの場合、xmlとかannotationでいろいろ設定しないといけない
最初、理解するためにSpringだけでやってみようとしたけど、設定で躓いて諦めた。。。
ライブラリを追加する場合でも、SpringBootがよしなにやってくれるのでかなり楽。
組み込みのWebサーバがある。
ビルドしたらjarが作られるので、配置先のサーバで
java -jar xxx.jar
でAPサーバが立ち上がる(!) Gradleだと、gradle bootRun
で一発(!)
Annotationつけるだけで、全部設定してくれる。
ある程度わかってくると楽になっていいけど、初めはつらいかも。。
How Google Worksを読んだ
How Google Works (ハウ・グーグル・ワークス) ―私たちの働き方とマネジメント
- 作者: エリック・シュミット,ジョナサン・ローゼンバーグ,アラン・イーグル,ラリー・ペイジ,土方奈美
- 出版社/メーカー: 日本経済新聞出版社
- 発売日: 2014/10/09
- メディア: 単行本
- この商品を含むブログ (17件) を見る
Googleがどのようにしてこれまでの成功を収めたのかについて書かれている本。
現在のインターネットによる変化が著しい時代(本の中では、"インターネットの世紀"と呼ばれてる)で成功するためには、 プロダクトの優位性が必要で、それがあればユーザーを獲得することができるし、あとから利益もついてくる。
プロダクトの優位性を得るには、既存の市場を参考にするのではなく これまでにない技術的アイデアによって実現されることが成功の鍵。
ex) Gmailだと、今までメールソフト使うのが常識だったけどブラウザで出来るようなったとかかな
ユーザーに焦点を絞るというのも、プロダクトの優位性を保ち続けるためのもので、ユーザーにとっての価値が最優先。
そのプロダクトを実現するには、専門性と実現力を備えたとても優秀な人材が必要で その人材のことが"スマートクリエイティブ"と呼ばれている。
スマートクリエイティブを獲得するために、 Googleは採用を経営者の一番重要な仕事だと考えていて、 中には"自分より優秀な人間を採用せよ"というルールがあるらしい。
ほかにもイノベーションや組織のマネジメントについても書かれており、 人材についてはGoogleみたいな企業しか出来ないこともあると思うけど(破格の報酬とか・・・)、 Googleが実践してきた手法を学べる良い本だと思いました。
PlayFramework2.3(scala)でDBアクセスをするときのめも
Play + ScalaでDBアクセスのめも
環境
DDLは↓
本来はEvolutionを利用して作るものだけど、今回は直接作成した・・・
CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `mail` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `mail_UNIQUE` (`mail`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
設定
SQLアクセスをするために、anormを使う
build.sbtの設定
必要なライブラリを追加
libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34" )
application.confの設定
DB接続設定の追加 それぞれ以下の変数は自分の環境に適宜変更する
HOSTNAME, SCHEMANAME, USERNAME, PASSWORD
db.default.driver=com.mysql.jdbc.Driver db.default.url="jdbc:mysql://_HOSTNAME_/_SCHEMANAME_" db.default.user="_USERNAME_" db.default.password="_PASSWORD_"
実装
Scalaの場合、Javaと違ってモデルを扱うためのライブラリがないみたい
Slickというライブラリが時期バージョンでデフォルトになるとかならないとか・・・
初めはSlickを試していたけどうまく動いてくれなかったので断念して、 anormを利用してみたところ使い勝手が良かったのでanormを利用することにした
モデルは、Javaと同様にapp/models
以下に作成していく
anormではモデルを作成するパッケージなどに特に縛りはなく、 コントローラにSQLを書いたりしても問題ないが、アレだと思うので
app/models
以下に作成していく
実際のソース
https://github.com/yamashiro0110/Play-ScalaSample/blob/master/app/models/User.scala
ハマった点.1: ~
って何?
~
については、以下のページに解説があった
http://libro.tuyano.com/index3?id=1069003&page=5 ここでの「~」という記号は、Anorm特有の機能で、値をリスト化する働きをします。例えば、A~B~Cとすると、((A, B), C)というようにまとめられます。こうしてまとめたものを元にMydataオブジェクトを生成するのが、その後のmap部分です。
ハマった点.2:object User.data
が何なのかよくわからない
data
については、SQLの実行結果をオブジェクトにパースするためのものみたい
以下のコードだとSQL(SQL文).on(条件).as(パーサ.戻り値)
となっている
def findById(id: Long): Option[User] = { DB.withConnection { implicit c => val sql = "SELECT * FROM user WHERE id = {id}" SQL(sql) .on("id" -> id) .as(User.data.singleOpt) } }
戻り値をOption[User]
にしたのは、指定されたIDがテーブルに存在しない場合にエラーが発生したため
パーサ(data
)からOption[User]
を取得するためには、singleOpt
を呼び出せばいい
User
を取得したい場合は、single
でいける
User
モデルを呼び出している部分はapp/controllers/SampleController
になっている
変数usr
に、IDが1のUserを探して代入、存在しない場合はUser.notFound
を代入している
レスポンスはCall SampleController index!! ->
という文字列にusr.name
を追加して返しているだけ
def index = Action { val usr = User.findById(1).getOrElse(User.notFound) Ok("Call SampleController index!! -> " + usr.name) }
Play + JavaのEbeanがクソ便利だったので、 Play + Scalaにはなかったことを知ったとき(とSlickを断念したとき)はJavaに戻ろうかと考えたけど、 anormもなかなか使いやすかったので今後もPlay + Scalaを利用していきたいと思った
あと、今回のソースをGitHubに上げました^^;
参考にしたページm(__)m
Model(モデル)を使ってデータベースアクセスする[Scala編](1/7):Herokuで始める 初心者のためのPlay Framework入門
リーン・スタートアップを読んだ
印象にのこったところ
- 顧客にとっての価値のあるもの以外はすべて無駄である
- 起業とはマネジメントである
- 仮設と検証による学びを繰り返して、製品を価値あるものに成長させる
- ピボット(方向転換)
- MVP(実用最小限の製品)
- 小さなバッチサイズ
今まで起業については、「当たれば成功」「外れたら取り返しがつかないほどの失敗」といった 超ハイリスクなギャンブルのようなものだと思っていた。
この本を読むことで起業した場合に、 リーンスタートアップではどのように仕事を 進めるべきなのかが実例をもとに解説されているため、 起業はギャンブルであるという印象はなくなった。
ただ、起業して本当に成功するためには努力と情熱が必要だし、 ほかにもまだまだ知らなければならないことがあると感じた。
YahooBB With フレッツ光でインターネットに接続できなくなったときのめも
家のインターネット回線をauひかりから、YahooBB フレッツ光に乗り換えたのだけど オプション解約などするとネットにつながらなくなったので、そのときの対応をメモ・・・
つながらなくなった経緯
2015/03/26に自動音声案内にそって、すべてのオプション解約手続きをしました。 (てかサポートがまじで電話とらん、ネット上では8時間掛けっぱなしにしても取らなかった人もいるとか・・・)
以下のページに記載の番号 http://ybb.softbank.jp/support/inquiry/hikari/301i.html
月が変わって、4/1に・・・
朝、スマホでFacebookやらInstagramのアプリを開くとネットワーク接続エラー・・・
ルータを再起動したりしてみるも、変わらず・・・
対応したこと
とりあえずルータにログイン(ルータはフレッツ光のもの)
自分のとこでは、http://192.168.1.1へアクセスするとBasic認証が行われたが、 メッセージにID,PWらしきものが記載されてたので、それでログインできた
"情報" > "障害ログ"とリンクをたどると、ルータのログがあった
以下ようなメッセージがあった
66. 2015/04/02 20:11:31 PPPの認証失敗[メインセッション] 67. 2015/04/02 20:11:31 PPP-LCPの確立[メインセッション] 68. 2015/04/02 20:11:31 PPPoE セッション開始成功[メインセッション] 69. 2015/04/02 20:11:31 PPPoE AC発見成功[メインセッション]
PPPの認証失敗だと・・・!? (PPP接続の認証情報とか見覚えがないし・・・)
家のPCでは、ネットがつながらないのでひたすらスマホでググってると PPPoE接続のID・パスワードの変更を行えるページにヒット(この間、約2日・・・)
https://ybb.softbank.jp/member/yf/index.php このページを表示するにも、契約時に発行されたYahooIDでのログインが必要
今回はPWがわからなかったので、PWだけ変更
変更が完了したら再度ルータの設定画面へ行き、PPPoE接続の設定を行う
基本設定 > 接続先設定(IPv4 PPPoE) > メインセッション
PPPoEのIDが'xxxxxxxxxxxx@sbb.ne.jp'のようになってたので、以下のように設定
接続先名:xxxxxxxxxxxx(IDがメールアドレスになってたのでアカウント部分を設定) 接続先ユーザー名:xxxxxxxxxxxx@sbb.ne.jp 接続パスワード:xxxxxxxx(先ほど設定したPW)
入力したら"設定"ボタンを押す
再度、"障害ログ"を見ると以下のログが・・・
1. 2015/04/02 20:15:37 PPP-IPCPの確立[メインセッション] 2. 2015/04/02 20:15:37 PPPの認証成功[メインセッション] 3. 2015/04/02 20:15:37 PPP-LCPの確立[メインセッション] 4. 2015/04/02 20:15:37 PPPoE セッション開始成功[メインセッション] 5. 2015/04/02 20:15:37 PPPoE AC発見成功[メインセッション]
認証成功キタ━━━━(゚∀゚)━━━━!!
https://www.google.co.jp/にアクセスすると、表示された!
一件落着( ´ー`)フゥー...
まとめ
YahooBBのオプションである光BBユニットを解約すると(?) PPPoEの認証設定を変更しないといけないぽい・・・
ネットつながらないから、サポートに電話してるってのに 全然とらないってどういうことだってばよ・・・ (WEBで手続き出来ますとか言ってるし)
光BBユニット解約したら認証設定必要とか聞いてないし、 オプション解約時の影響とか手元の資料見ても全然わからんし・・・ (この辺は確認不足もあるかも)
おかげで、スマホの通信料を無駄遣いしてしまった・・・
いろいろと文句が多くなっていますが、 同じような現象で困っている人の助けになれば幸いです(-_-;)
Written with StackEdit.