java8移行から始めた技術的負債との戦い(jjug ccc 2015 fall)

Post on 07-Jan-2017

19.468 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Java8 移行から始めた技術的負債との戦いJJUG CCC 2015 Fall2015.11.28

清 大輔 @ 株式会社ビズリーチ

2

発表者 清 大輔 株式会社ビズリーチ 新卒2年目 エンジニア 博士課程中退な人• カオス・フラクタル• 脳波解析• やっぱりプログラム書いてたほうが楽しいのでエンジニアへ

趣味や研究でプログラム書いてました• 基本 C++ とか

3

ビズリーチについて Mission インターネットの力で、世の中の選択肢と可能性を広げていく

4

BizReach

ビジネスパーソン、国内外の優良・成長企業、各業界に精通した一流ヘッドハンターの三者を最適かつ効率的にマッチングする管理職・グローバル人材に特化した会員制転職サイト

5

BizReach woman

女性が、理想のキャリアを追求・確立するために、多くの可能性と選択肢から最もふさわしいキャリアを見つけるための転職サイト

6

careertrek

日本で初めて全職種に対応した求人レコメンド型 20 代向け転職サイトで、キャリア診断結果をもとに求職者と企業をマッチングするだけでなく、使えば使うほどマッチング精度が高くなるレコメンド機能を搭載

7

スタンバイ インターネット上にある国内のさまざまな求人情報約

300 万件を一カ所に集約し、いつでもどこでも、簡単に、効率的に仕事を探せるサービス

8

RegionUP

アジアの優秀なビジネスパーソンと、ハイクラス向けを中心とした求人情報を提供するアジアの企業・ヘッドハンターをつなぐ「アジア版ビズリーチ」

9

zuknow

スマートフォンとソーシャルの力を使って学習を効率的で楽しいものに変える学習アプリ

10

ニクリーチ お腹を空かせた学生のための肉食就活サイト 自分が興味のある企業の人と、無料でおニクが食べら

れ、様々なキャリアをもった人とじっくり話せる

11

前置きはここまでにして

12

移行対象 : BizReach

システムの基盤を作った人達が他の新規事業に行ったりしてしまってチームにいない

pom などのメンテをする人が特に決まっていないような状況• フレームワーク等のバージョンのアップデートが遅れていた• 技術的負債が溜まっていた

13

ビズリーチシステム( Java8 移行前) 使用している技術• 言語 : Java6• MVC: Struts2• DI: Spring3• View: JSP, Velocity … JSP → Velocity へ(混在中)• ORM: DBFlute 1.0.x• 他 : DWR, AWS, etc

開発環境 : Eclipse 3.7 Indigo

14

移行のきっかけ Java8

→ Stream, ラムダ式 , Optional 使いたい!!

List<String> codes = new ArrayList<>();for (Bean bean : list) {

codes.add(bean.getCode());}

List<String> codes = list.stream().map(bean-> {return bean.getCode();

}).collect(Collectors.toList());

for Java7

for Java8

15

移行のきっかけ Java8→ 使っているライブラリーも Java8 の方が書きやすい!!

MemberCB cb = new MemberCB();cb.query().setMemberId(1L);Member member = candidateBhv.selectEntity(cb);String memberStatusCd = member == null ? “” : member.getMemberStatusCd();

String memberStatusCd = candidateBhv.selectEntity(cb -> { cb.query().setMemberId(1L);}).map(Member::getMemberStatusCd).orElse(“”);

DBFlute for Java7

for Java8

16

移行のきっかけ Eclipse Luna (Release Candidate)• Eclipse Kepler でもプラグインで対応できたがそちらは微妙に不安定• Luna だとかなりましになった→ そろそろ Java8 で書けそう?

17

移行のきっかけ Eclipse Luna (Release Candidate)• Eclipse Kepler でもプラグインで対応できたがそちらは微妙に不安定• Luna だとかなりましになった→ そろそろ Java8 で書けそう?

というのもありましたが

18

移行のきっかけA 「 Java7 のサポート切れるよね〜」B 「そうですね〜」A 「 Java8 に上げないの?」B 「(あれ?そもそもうちまだ Java6 じゃん)  上げます!!」

2015 年 4月下旬移行開始

19

事件 1. ラムダ書くとそもそも開発環境で起動しない20

21

事件 1. そもそも起動しない事象 ラムダを書いた瞬間から、 Eclipse 上でアプリ

が起動してくれない

22

事件 1. そもそも起動しない事象 ラムダを書いた瞬間から、 Eclipse 上でアプリ

が起動してくれない

Java8 にする意味 …

23

事件 1. そもそも起動しない背景 起動には Eclipse の Run Jetty Run (RJR) プラグ

インを利用していた RJR プラグインは 2013 年に開発ストップ 最新で Jetty 8 で起動

24

事件 1. そもそも起動しない原因 実は Jetty9.2.x で Java8 に対応している

= それ以前のバージョンだと未対応

25

事件 1. そもそも起動しない原因 実は Jetty9.2.x で Java8 に対応している

= それ以前のバージョンだと未対応

問題 RJR プラグインには Jetty 8 までしかない

26

事件 1. そもそも起動しない対応 急遽 RJR プラグインを fork して最新の Jetty で起動できるようにしてメンバーに配布

27

事件 1. そもそも起動しない対応 急遽 RJR プラグインを fork して最新の Jetty で起動できるようにしてメンバーに配布

起動した!!(まだスタート地点)

28

事件 1. そもそも起動しない教訓 開発の止まっているものは使わない• 止まっているのは理由があることが多い

Eclipse プラグインに頼りすぎない• Eclipse プラグインを作るのは案外辛い

組み込み AP サーバー化すべき• プラグインからの脱却• 開発 / 本番一致( The Twelve-Factor App)

29

さて、デプロイして動作確認しよう…

事件 2. 検証環境だとラムダで死ぬ

30

31

事件 2. 検証環境だとラムダで死ぬ事象 検証環境でデプロイが失敗した!?

→ アプリが立ち上がってない…

32

事件 2. 検証環境だとラムダで死ぬ背景 本番にリリースする前に検証用の環境にデプロ

イして動作確認を行っている ローカルだと Jetty を利用しているが検証及び

本番の環境では Tomcat 8 を利用していた

33

事件 2. 検証環境だとラムダで死ぬ原因 古い ASM( 3.x)ライブラリが足を引っ張っ

ているようだ• Java8 対応は ASM 5.x• バイトコード周り?(自分は詳しくない)• Spring のバージョンを 3.2.9以上にあげるしかない

• 公式ブログのアナウンスより

34

事件 2. 検証環境だとラムダで死ぬ対応 Spring のバージョンを 3.2系にあげる• Spring 4 は諸事情により見送り

• 一気にいろいろやるのは怖い

35

事件 2. 検証環境だとラムダで死ぬ対応 Spring のバージョンを 3.2系にあげる• Spring 4 は諸事情により見送り

• 一気にいろいろやるのは怖い

検証でもでラムダが動いた!!

36

事件 2. 検証環境だとラムダで死ぬ教訓 実はフレームワークのマニュアルやブログに全部開いてあるので、事前にきちんと読もう

37

これで安心してラムダが書けるようになった

事件 3. Action でラムダ書くとそこで死ぬ

38

39

事件 3. Action でラムダ書くと死ぬ事象 Action でラムダ書いたら、その Action にリクエ

スト投げるとエラーで落ちる@Namespace("/")public class IndexAction {

@Action(value = "", results = {@Result(name = SUCCESS, location = “home.vm“)})

public String index() {return SUCCESS;

}}

← 例えばここらへんに追加

40

事件 3. Action でラムダ書くと死ぬ事象 Action でラムダ書いたら、その Action にリクエ

スト投げるとエラーで落ちる Action のクラスに書かなければ落ちない↑ これのせいでちょっと発見が遅れた

41

事件 3. Action でラムダ書くと死ぬ原因 struts2-java8-support-plugin が必須• 2015/05/03 に出た• Java8 化リリース予定の 1週間前

42

事件 3. Action でラムダ書くと死ぬ対応 struts2-java8-support プラグインを入れる

43

事件 3. Action でラムダ書くと死ぬ対応 struts2-java8-support プラグインを入れる

Action でラムダが動いた!!

44

事件 3. Action でラムダ書くと死ぬ教訓 行き当たりばったりは良くない• でも Java8 で行くって言っちゃったし …

無意味でも M, V, C とかいろんな場所にラムダを書いて炙り出しをしておくべきだった

45

もうそろそろ大丈夫そう?

事件 4. Mac PC だとラムダで死ぬ

46

47

事件 4. Mac PC だと死ぬ事象 Windows PC では動作しているのに Mac PC だと

ラムダ書いた場所でエラー 原因は不明

48

事件 4. Mac PC だと死ぬ背景 開発環境が Windows PC から Mac PC へ一斉

に移行される予定だった• MacBook がいつ納品されるのかよく分からない!?• Windows と Mac の混在状況が予定よりも長く続く

Mac 移行を先行した人(人柱さん)が無事地雷を踏んだ模様

49

事件 4. Mac PC だと死ぬ対応までの流れ ORM に DBFlute を使用 DBFlute の Java8 対応版へのバージョンアップ

を試作していた(後方互換なし)• 次のリリース直後に一気に移行作業、な予定だった

なぜか DBFlute Java8 対応状態では正常に動作 予定を繰り上げて決行

50

事件 4. Mac PC だと死ぬ教訓 Point of No Return を短いスパンでいくつも超え

るのは怖いが案外なんとかなる• もちろんやらないほうがいい

51

Windows ・ Mac PC 混在状況 両方の環境で動くようにメンテする羽目になる 両方の環境の手順書を維持する羽目になる

52

Windows ・ Mac PC 混在状況 両方の環境で動くようにメンテする羽目になる 両方の環境の手順書を維持する羽目になる

結構辛い…

事件 5. デザインツールの挙動がおかしい

53

54

事件 5. デザインツールが動かない背景 PDF の生成には Jasper Report というライブラ

リを使用していた デザインには専用のツールが必要

55

事件 5. デザインツールが動かない事象 Jasper Report のデザインツールが Java8 だとお

かしな挙動をする 開発者のデザインツールがまともに動かないと

いうことで、 PDF のデザインフォーマットが変更できない

56

事件 5. デザインツールが動かない原因 件のツールでは JDK6 が必要

57

事件 5. デザインツールが動かない対応 取り合えず PDF のフォーマットに関わる仕様変更をしばらく凍結• 緊急案件なら JDK6 をいれていただく

Jasper Report 撲滅へと乗り出す

58

事件 5. デザインツールが動かない教訓 バージョンを飛ばすと当然踏む地雷は増える• 妥当に踏みました

59

ここまでで増えたタスク 組み込み AP サーバー化 Jasper Report 撲滅作戦 Spring 4 へのバージョンアップ

組み込み AP サーバー化

60

61

組み込み AP サーバー化目的 Eclipse プラグインからの脱却• Run Jetty Run プラグインのメンテしたくない

開発環境と本番環境で使うものを合わせる• 本番環境だけで問題発生、といったことを防ぐ

手段 組み込み Tomcat を使用する

62

組み込み Tomcat

以下のように書く

docBase には webapp フォルダを設定• WEB-INF を持つフォルダ• ソースを見ると *.war でもいけそうだったが、やってみたところ異様に起動が重かった

Tomcat tomcat = new Tomcat();Context context = tomcat.addWebapp(contextPath, docBase);tomcat.start(); tomcat.getServer().await();

63

なんだかんだで起動までいったところで…

事件 6.JSP の描画で死ぬ

64

65

事件 6. JSP の描画で死ぬ事象 JSP をビューとして使用するページで

500 Internal Server Error

66

事件 6. JSP の描画で死ぬ原因 Jasper Report が依存している EL 式のライブラ

リーが古く、そちらの方を読み込んでしまって関数が見つからない

67

事件 6. JSP の描画で死ぬ原因 Jasper Report が依存している EL 式のライブラ

リーが古く、そちらの方を読み込んでしまって関数が見つからない

また Jasper Report

68

事件 6. JSP の描画で死ぬ対応 本番への組み込み AP サーバー適用は Jasper

Report を撲滅してからにする 直近はローカル環境でのみ組み込み AP サー

バーで動くように pom をいじる ( Jasper Report 撲滅後)全プロダクトで一斉に切り替えるのは怖いので少しずつ移行• Maven profile で切り替え

69

組み込み Tomcat 化現状 本番サーバーでの組み込み化は完了 運用開始後、特にトラブルはない• びびって小出しにする必要はなかった• 問題がないと逆に不安になる

Jasper Report 撲滅作戦

70

71

Jasper Report 撲滅作戦作戦 Flaying Saucer (with Atlassian’s Patch) を使用• 日本語周りのバグを Atlassian さんが修正したもの• Html ファイルを PDF 化するライブラリ

粛々と置き換える• デザインを Html へ落とし込む

72

Jasper Report 撲滅作戦作戦 Flaying Saucer (with Atlassian’s Patch) を使用• 日本語周りのバグを Atlassian さんが修正したもの• Html ファイルを PDF 化するライブラリ

粛々と置き換える• デザインを Html へ落とし込む

無事リリース

事件 7.ダメ文字で死ぬ

73

74

事件 7. ダメ文字で死ぬ事象 垂直タブが含まれているとそこまでで処理が終

わってしまう→ 中途半端な PDF が出力されてしまう

75

事件 7. ダメ文字で死ぬ事象 垂直タブが含まれているとそこまでで処理が終

わってしまう→ 中途半端な PDF が出力されてしまう

対応 ダメ文字を入力時と出力時にフィルタリング

76

事件 7. ダメ文字で死ぬ教訓 ユーザーの入力は信用しない DB に入っているデータも信用しない ライブラリへの入力は慎重に あらゆる入力は信用できない

Spring 4 移行作戦

77

78

Spring 4 移行作戦 Spring 3.x → Spring 4.x へ Spring 4.1 だと Quartz Scheduler 周りでコンパ

イルエラーになったので Spring 4.0 へ• Quartz Scheduler 移行は後で

修正は pom の中のバージョンを上げるだけ

79

Spring 4 移行作戦 Spring 3.x → Spring 4.x へ Spring 4.1 だと Quartz Scheduler 周りでコンパ

イルエラーになったので Spring 4.0 へ• Quartz Scheduler 移行は後で

修正は pom の中のバージョンを上げるだけ検証で問題なかったのでリリースしてみた

事件 8.秋の OOM祭り

80

81

事件 8. 秋の OOM祭り java.lang.OutOfMemoryError: Metaspace• Java 8 でクラスなどを確保する領域を Metaspace といい、 Native メモリとして扱われる

リリースしてからちょっと経ってから出始める→ とりあえずインスタンスタイプ( AWS)

を あげると収まった

82

事件 8. 秋の OOM祭り原因究明 Spring 4.0 はリクエストを処理した時にクラス数が増加

Spring 4.1 はリクエストを処理した時にクラス数が変わらない

Spring 4.1 へ

83

Spring 4.1.x へ背景 Spring 4.1 以上では古い Quartz Scheduler の方

式はサポートしなくなった作戦 Spring Batch の方式で書き直す ついでに Spring 4.1 にアップデートする• ちなみに Spring 4.2.x だと DWR というライブラリーが死ぬ

84

Spring をバージョンアップ結果 メモリーの使用状況を見る限りバージョンアッ

プ後もあまり変化はなかった マシンスペックが上がったことで安定して稼働

しているので、そもそもメモリーが足りていなかったのかもしれない

85

事件 8. 秋の OOM祭り結論 金の力は偉大である

並行して行っていたこと

86

87

ついでにいろいろ導入 Mac導入など環境の作り直しもあって環境周り

の見直しなどを行っていた= 技術的負債返済の一環

• Vagrant による環境構築手順の簡略化• パスワードなど重要な情報を環境変数へ

• Spring 3.1.x からの機能で、 propertyt 値を上書きできる• Lombak• Java Config 化• `mvn -Dmaven.test.skip=true` をやめる

88

Vagrant

仮想環境構築ツール 設定を作る人が頑張れば後の人が楽できる コマンド数発で MySQL 等のミドルウェアのセットアップが終了

PC のスペックと要相談

89

Vagrant

使用している PC• MacBook Pro• プロセッサ : 3.1 GHz Intel Core i7• メモリ : 16 GB 1867 MHz DDR3

現在仮想環境で動作中のもの(割り当て :2GB)• MySQL• PostgreSQL• Redis• Cassandra• Solr

90

Lombok – 紹介 ボイラープレートコードを解消するためのツール• 自明だが省略できないお決まりのコード断片

例えば Getter や Setter をクラスの先頭にアノテーションをつけるだけで自動生成されたことになる

@Getterclass Foo {

private String bar;}

class Foo {private String bar;public String getBar() {

return bar;}

}

=

Lombok – よく使うもの @Getter, @Setter• 前述の通り

@Data• クラスの先頭につけておくだけで Getter/Setter, toString,

equals, hashCode が実装したことになる @Value• Immutable なオブジェクトの定義

etc

92

Lombok – メリット・デメリットメリット コードがすっきりと簡潔になる 実はテストのカバレッジに効く• コード自体は書かないので

デメリット 若干検索性が下がる 変数名の変更時などに若干手間

93

Java Config 化 XML は補完が効かなかったり、リファクタリ

ング時に修正を忘れて事故ることがよくある Java Config にすれば Java のコードで設定をか

けるので IDE の補助が効き、また if 文の利用など小回りがきく

94

Java Config 化 以下のような書き換えを行う

<bean id=“foo” class=“jp.bizreach.Foo” />

@Configurationclass Config {

@Beanpublic Foo foo() {

return new Foo();}

}

95

テストの実行 事業会社はスピードが最重要とはいうけれど、そろそろテストが実行されないのはまずい

ようやく Unit Test や Integration Test の自動実行の環境が整った• Unit Test: JUnit4• Integration Test: Selenium WebDriver

• Vagrant で環境を作り、 DB には DBFlute 付属の機能でデータを流し込み、 Solr のインデックス処理を行う関数(自作)を実行し、 Selenium WebDriver による Integration Test を実行

96

テストの実行 本格運用はこれから• まだ全然テストが書かれていない

これから長い旅が始まる

97

他のこまいの Optional#orElseThrow が開発環境だと問題ない

が検証環境だとビルドがこける Optional#orElseThrow の中で throw すると開発環境だと問題ないが検証環境だとビルドがこける

Eclipse で、ちょっと複雑な Lambda 式でコンパイルエラーになったりする

etc...

まとめ

98

99

Java8 化にあたって フレームワークやライブラリーが古い状態だと同時多発的に問題が起こる

技術的負債が表面化し、いつの間にかそれとの戦いが中心となっていた

Java8 化する前にすることはいっぱいあった

100

Java8 にする前に 各種フレームワークは最新版に 組み込み AP サーバー化する Jasper Report とお別れする Eclipse プラグインに依存しない

101

Java8 化等いろいろしての実感 Lambda 使えるようになって、コード量が減り、

可読性が上がった Stream でうまい感じで処理を書くことができる

と気持ち良い Lombok が便利• @Data, @Value, @Builder, @Slf4j, …

XML ファイルをいじることがなくなった

102

Java8 化により得られたこと これからの動きに追従できる• Spring 5 は Java 8+• DBFlute 1.1 など、 Java8 に対応・最適化されたライブラリ・フレームワークが出てきている

• Lambda の出現により書き方の最適解が変わった• Java 9 が見え始めている

103

これからやっていくこと JSP はやめたい• 少なくとも混在状況がよくない• 撲滅運動進行中

DWR をやめたい Struts2 もおさらばしたい• 新アーキテクチャーへの移行計画

104

これからやっていくこと JSP はやめたい• 少なくとも混在状況がよくない• 撲滅運動進行中

DWR をやめたい Struts2 もおさらばしたい• 新アーキテクチャーへの移行計画

まだまだ道半ば

105

お知らせ

ビズリーチではJava でサービス開発したい方

大募集!

106

お知らせ 弊社オフィスのイベントスペースを使用して

様々な勉強会を行っております 会場提供も可能です

107

We are hiring!

top related