LINE株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。 LINEヤフー Tech Blog

Blog


JJUG CCC 2018 Fall参加レポート

きしだです。

12月15日に開催された国内最大のJavaコミュニティイベントJJUG CCC 2018 FallでLINEはGoldスポンサーとして協賛し、またSushiスポンサーとして懇親会で回る寿司を提供しました。

LINEからは、スポンサーセッションとして藤原 聖さんが登壇してKotlinの話をしたほか、松野 徳大さんも広告プラットフォームで利用している技術の紹介を行いました。また、実はこの日からLINE社員になっていた久保田 祐史さんもJava8からJava11への移行の注意点について登壇しています。
きしだも、基調講演でのパネルディスカッション、Java 11 APIについてのセッション、懇親会でのSushiスポンサーLTと、3枠で登壇を行いました。
このエントリーでは、それぞれのセッションの内容の紹介と、SushiスポンサーLTで出題したクイズの解説を行います。

【JJUG基調講演】Javaの未来を考えよう

概要に名前は載っていませんでしたが、「Javaの未来を考えよう」というテーマで、谷本 心さん、阪田 浩一さんとともにパネルディスカッションを行いました。モデレータの鈴木 雄介さんが子どもをあやしながら司会を行うという、ほのぼのとした見た目のセッションになりました。

パネルディスカッションのテーマとしては、写真には3つのテーマが出ていますが、「Javaに限らず世の中で注目は?」の部分も結局Javaの話になっていたので技術の話とコミュニティの話になりました。

技術的な話として、ぼくはGraalVMのネイティブイメージの話をしました。

GraalVMは、Javaで書かれたJITコンパイラであるGraalと、その最適化機構を動的型付け言語から利用するフレームワークであるTruffleを中心とした、多言語実行環境です。
この中に、JITコンパイラであるGraalをAOTコンパイラとして使って、Javaのバイトコードをネイティブコードに変換して実行バイナリを作成する機能があります。そうするとJVMの起動やクラスの読み込みがなくなり、Javaの欠点である起動時間の遅さが解消されます。そうして利用範囲が広まることで、Javaの未来として新しい道が開けるんではないかと思っています。
また、Micronautという、GroovyフレームワークのGrailsを開発していたチームが新しく作ったフレームワークがあるのですが、DIをコンパイル時に解決することで、Spring Frameworkのように実行時にDIを解決して起動時間が長くなるという問題を解決しています。また、フレームワークとしてGraalVMのネイティブイメージに対応していて、ネイティブ化することでさらに起動時間が速くなります。
このような、起動時間を速くするという方向性が生まれているのが、面白い進化だなと思っていて、紹介させてもらいました。

他には、リリースサイクルの話になったときに、たぶん谷本さんだったと思うのですがリリースサイクルが早くなることで強制的に勉強する必要がでて、コミュニティが活性化するのがよいということを話していて、面白い視点だなと思いました。

そしてコミュニティの話につながるのですが、谷本さんは東京でJJUGの幹事であり、阪田さんは関西で関ジャバというコミュニティの代表で、そして きしだも福岡でJavaのコミュニティを運営しています。このように3人ともコミュニティ運営を行なっているということもあって、いろいろな議論が飛び交いました。

コミュニティへの貢献をどうするか、という話について、発表など情報を受け取るだけでなく発信もしてほしいという話題もありましたが、参加したら参加者カウントがあがるというのが大きいという話をしました。特に地方や話題が絞られたコミュニティでは人数が少なく、自分が参加することで1人が2人に、2人が3人にと1人ふえることの影響力が大きいので、好きな技術のコミュニティにはぜひ参加して欲しいと思います。大きなコミュニティでも、たとえば地方の参加者が0から1人に、のように、自分の属性についてカウントがひとつあがるというのは、コミュニティが自分に都合のいい方向に動くきっかけになります。
情報発信をすると、自分の都合のいい方向に世の中がかわってくれます。技術の世界でいうと、こういう不具合が延々発生するのは嫌だとか、こういう知識は前提として次の話をしたい、この話題について一緒に話せる人を増やしたい、とか、そういった方向には情報発信を続けることで結構変わってくれると思っています。

あと、Javaへの貢献という話題で例に出したのが、Strutsの事例です。Strutsは日本では多く使われていたけど開発コミュニティへの参加が少なかったのでStrutsのサポート終了を覆せなかった、という話ですが、こちらの日経コンピュータの記事をもとにしています。
オープンソースソフトウエアにも寿命がある | 日経 xTECH(クロステック)
これは逆に、情報発信をしなかったことで、自分の都合の悪い方向に世の中が変わったという話ですね。
17:45から海外からの参加者も交えたCommunity Leader Meetupというアンカンファレンスがあったのですが、海外では利用しているオープンソースプロダクトへのコミットが少ないことはリスクになるということで、株価が下がることもあるという話をされている方もいました。
いまだと、5月からの新しい元号への対応がJavaに入ってる最中で、この機能はほとんど日本人にしか影響がないと思うのですが、メーリングリスト上でほとんど日本人による議論がほとんど行われていません。その結果、元号を扱うときに必要な機能が実装されない可能性があります。このブログを読んでる人には元号を扱うシステムを作っている人の割合が少ないかもしれませんが、もし元号を扱うシステムをJavaで作っているのであれば今からでもOpenJDKのCoreライブラリ開発者国際化対応のメーリングリストでの議論に参加してみてはどうでしょうか?

LINE で広告プラットフォームを Java + Golang で立ち上げた話

セッションとしてLINEで最初に登壇したのは松野さんです。@tokuhirom として有名ですね。

LINEのサービスに広告を配信するプラットフォームであるLINE Ads Platformの紹介と、ポリグロット(多言語)環境を踏まえてどのようなアーキテクチャを構築したかという話をしていました。

資料の中でSSP、DSP、DMPという用語がありますが、それぞれ次のようになっています。

  • SSP(Supply Side Platform) 広告掲載メディア側のプラットフォーム
  • DSP(Demand Side Platform) 広告出稿側のプラットフォーム
  • DMP(Data Management Platform) データを分析してSSPやDSPに最適化のための情報をあたえるプラットフォーム

これらがどのようなやりとりを行うかというのは、IABというオンライン広告の業界団体でOpenRTBとして決められていて、だいたいどこでも同じような構成になるとのこと。

そして、このような広告配信システムを新規で開発することになったのですが、開発拠点が日本・韓国の複数の拠点にまたがっています。ということで、あぁポリグロットというのは日本語と韓国語、英語などのやりとりの話かなーと思ったのですが、そうではなく。
開発スピードを重視するために各チームが得意な技術を使うという方針をとったところ、Javaがメインではありますが、KotlinやGo、Scalaなど複数の開発言語が使われることになったと。プログラミング言語が複数使われるという意味でのポリグロットですね。また、国によって技術の流行りが違うので、チーム間の引き継ぎを考えてほかの拠点で使われてない言語は使わないようにしたということです。
そうやって、多言語で作ったシステムの連携のために、Kafkaをメッセージキューとしてはさんでシステム間を疎結合にし、シリアライズにはApache AvroやProtocol Buffersを使って実装環境に依存しないようにしてるということです。

LINEで広告プラットフォームをJava+Golangで立ち上げた話 from LINE Corporation

生粋のKotlin LoverによるLINEのKotlinの話

スポンサーセッションとしては藤原さんがKotlinの話をしました。内容としては大きくわけて、Kotlin 1.3の新機能の紹介と、Kotlin Konf 2018の様子、LINEでのKotlin利用についての話でした。

Kotlin Conf 2018はアムステルダムで開催されたのですが、LINEのエンジニアには海外カンファレンス参加を支援してもらえる制度があるので、その制度を使って8名が参加していたということです。
そのときの様子を紹介したブログはこちらです。
KotlinConf 2018 参加レポート - LINE ENGINEERING

Kotlin 1.3の新機能としてはCoroutinesが大きくインパクトがありますが、個人的にはKotlinのインラインクラスは面白いなと思いました。

inline class Password(val value: String)

val securePassword = Password("Don't try this in production")

というコードが、コンパイル後は単なるStringとして扱われるというもので、無駄なクラスが省かれていいと思いました。

また、LINEでのKotlinの話ですが、藤原さんが語られていたように、Androidでは多くがKotlinに移行して、新規アプリはKotlinになっているようです。
サーバーサイドでも松野さんのセッションでも紹介されていたように、Kotlinが使われ始めています。フレームワークにはSpring Frameworkを使って、非同期処理やSQL定義、テストに使われているようです。

ここでちょうどこの前の日にJavaとKotlinが混じったプルリクエストを読んだところだったので、質問者として手をあげて出しゃばってみました。


ぼくが読んだプルリクエストでは、テストにKotlinが使われていたのですが、予備知識なしに全部Javaだと思いながら読んでいると、なんかコンパイル通らないコードだなと思って、気づいたらKotlinだったという感じです。

生粋のKotlin LoverによるLINEのKotlinの話 from LINE Corporation

Migration Guide from Java 8 to Java 11

ちょうどこの日からLINE社員となった久保田さんの、Java 8からJava 11への移行の注意点に関するセッションです。

Java 9やJava 10はサポート期間が半年だったことから実運用で使われることは少なく、Java 8から移行する次のバージョンはLTS(Long Term Support)があるJava 11になります。
このセッションでは、Java 8からJava 11への移行について、Java 8でコンパイルしたものをそのままJava 11で使う、Java 11でコンパイルしなおして使う、というふたつのアプローチについて解説していました。

Javaではバージョンごとに移行時の注意点をまとめたマイグレーションガイドがありますが、移行後のテストが実行できるようにするためのガイドで、これに従えばテストしなくていいというものではないということです。

Java 8でコンパイルしたものをそのままJava 11で使うと、varなど新しい言語機能や追加されたAPIは使えませんが、無償化されたFlight Recoderでモニタリングを行ったり、GCなどJVMの改善の恩恵を受けることができます。
一方、Java 11でコンパイルしなおすという場合には、新しい言語機能やAPIを使いやすくなる一方で、コンパイルを通すためにもライブラリの更新が必要だったり、Java 8への対応ができなくなるなどの注意点があるとのことです。

削除されたり使えなくなったAPIにも対策が必要です。Java 9からJEP-277としてAPI非推奨の方針が整理され、forRemovalとして@DeprecatedのついたAPIは次以降のバージョンで削除される可能性があります。実際にJava 11でもThreadクラスのdestoryメソッドなどが削除されていますね。とくにJava 11ではJEP-320としてJava EEやCORBA関連のAPIが削除されており、注意が必要です。また、sunパッケージなどで内部利用のために用意されていたAPIをリフレクション経由で使っていた場合もモジュール化で制約が強くなったことにより使えなくなります。
Java EEやCORBA関連のAPIに関しては外部ライブラリ導入で対応できますが、そのほかの削除されたり使えなくなったAPIについてはコードの修正が必要です。問題はJava8とJava9以降の両方に対応する場合で、リフレクションを使って呼び出すAPIを切り替えるということを紹介されていましたが、これを久保田さんは「地獄の釜」と呼んでいました。

Migration Guide from Java 8 to Java 11 #jjug from Yuji Kubota

JShellではじめる最新Java

Java11のAPIをJShellで試すというセッションです。サンフランシスコでのOracle Code One 2018で行なったセッションのダイジェストになっています。

JDK 11の機能を紹介するとともに、JShellに慣れてもらえればなぁというのもありました。
こちらは、資料の通りに進めたので、参考にしていただければと思います。
Learn JDK11 with JShell (2018/12/15 JJUG CCC 2018 Fall) - Qiita

懇親会

今年も懇親会で寿司がまわりました!

ということでSushiスポンサーとしてLTを行いました。

今回は2問ほどJavaに関する問題を出したので、ここで解説します。

  • 問1. 平成が終わって元号が変わりますが、DateTimeFormatterで元号を表示するための文字はなんでしょう
  • 問2. Java5からGenericsが導入されクラスに型パラメータが指定できるようになりましたが標準APIでもっとも多く型パラメータに使われている文字はなんでしょう?

問1についてですが、DateTimeFormatterのJavaDocを見てみましょう。
DateTimeFormatter (Java SE 11 & JDK 11 )

フォーマット文字について次のようになっています。

ここでフォーマット文字Gの例になっているのは西暦だけですが、JapaneseDateを渡せば元号が表示されます。

jshell> import java.time.format.DateTimeFormatter

jshell> import java.time.chrono.JapaneseDate

jshell> var f = DateTimeFormatter.ofPattern("G")
f ==> Text(Era,SHORT)

jshell> f.format(JapaneseDate.now())
$8 ==> "平成"

ということで、問1の答えはGですね。

問2は、型パラメータで最も多く使われている文字はなんでしょう?という問題でした。
型パラメータというのは、例えばjava.util.ListだとEが指定されているジェネリクスの部分です。

このために、次のようなコードで型パラメータの文字数を数えました。

public class Counter {
    public static void main(String... args) throws Exception {
        var path = "/Users/naoki/java/jdk/docs11/api";
        var docRoot = Path.of(path);
        var pattern = Pattern.compile("<h2 .+">(Class|Interface) ([a-zA-Z0-9]+)<([a-zA-Z0-9, #&;]+)></h2>");

        Files.walk(docRoot)
                .filter(p -> p.toString().endsWith(".html"))
                .flatMap(unchecked(Files::lines))
                .map(pattern::matcher)
                .filter(Matcher::find)
                .map(mat -> mat.group(3).replaceAll("​", ""))
                .map(s -> s.replaceAll("<[A-Z,]+>", ""))
                .flatMap(t -> Arrays.stream(t.split(",")))
                .map(t -> t.substring(0, 1))
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet().stream()
                .sorted(Comparator.comparing(Entry::getValue))
                .forEach(System.out::println);

    }
    interface IOExec<T, U> {
        U exec(T t) throws IOException;
    }
    static <T, U> Function<T, U> unchecked(IOExec<? super T, ? extends U> exe) {
        return param -> {
            try {
                return exe.exec(param);
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        };
    }
}

ここで.map(s -> s.replaceAll("&lt;[A-Z,]+&gt;", ""))としているのは、Genericsのなかに複数の型パラメータがあるGenericsをもつBaseStream<T, S extends BaseStream<T, S>>というインタフェースに対応するためです。
結果は次のとおりTが最上位でした。

T=65
R=56
P=49
E=49
V=32
K=15
U=6
S=5
M=3
A=2
I=2

ところでこのコードのuncheckedのように検査例外をラップするメソッドが標準で欲しいところですね。

というわけで、問2の答えはTでした。
そこで、ふたつ合わせるとGT!

と、2018年6月に設立されたLINE Growth Technologyの紹介につなげました。
LINE Growth TechnologyはLINEでのサービスの継続的な成長を担うための会社です。
LINE Growth Technology株式会社 (LINE GT)

採用情報はこちらですので、興味がある方はぜひ応募を検討してください。
募集職種一覧 | LINE Growth Technology株式会社 (LINE GT)

JJUG CCC 2018 Fall 懇親会LT from LINE Corporation