英語JVM Advent Calendar ではどんなことが書かれているか

仮想スレッドについて書こうと思ったけど、先に書かれてしまっていたので、ネタ探しで見つけた英語のJVM Advent Calendarにについて紹介。海外のJava界隈の雰囲気が感じられて面白い。コメントは超ざっくり目を通しただけなので、あんま信じないでください。英語苦手でもDeeplとかで読めると思います。

 

www.javaadvent.com

 

Jet Brainsなんかもスポンサーしている。

1日目 Mockを活用したサービス仮想化アプローチはいかにしてあなたと他人の時間を節約するか

How a service virtualization approach can save your and others' time playing with mocks - JVM Advent

 

  • 複雑な外部サービスの仕様を網羅するんじゃなくて、自分たちでコントロール可能な外部仕様を偽装するサービスを作った方がいいよって話かな。

 

2日目 2つの都市の物語:ブロッキング呼び出しはどう扱われてきたか

A tale of two cities: how blocking calls are treated? - JVM Advent

  • Javaの並行処理の歴史:正直、こちらの記事の方が細かく書かれているかな?

Java in the Box Annex: Virtual Thread導入の背景 - Javaのマルチスレッドの歴史を振り返る

 

3日目 Eclipse Collectionの隠された宝

HIDDEN TREASURES OF ECLIPSE COLLECTIONS 2022 EDITION - JVM Advent

  • Eclipse Collectionの細かい仕様の解説

 

4日目 そのAPIを消すな!

Don’t remove the API - JVM Advent

  • マイクロサービスのAPIマイグレーションについて、これはあとでちゃんと読んでおこうかな。普通のこと書いてる印象だが。

 

5日目 Spring Security の新しい認可サーバー

A new Spring Security authorization server - JVM Advent

  • 読んで字の如し。個人的に、あんまり、ちゃんとしたシステムで使う気にはならない機能だけど、内部向けの雑なやつなら使えるのかな。

 

6日目 JavaのLambdaにおける例外

Exceptions in Java Lambdas - JVM Advent

  • Java Bad Partsにも挙げられるチェック例外をLambdaで扱うとき、ライブラリ使ってスッキリ書きましょう、という話。例外についての簡単な経緯とかもあるので、読んでみても良さそう。(個人的に気にせずtry-catch書いちゃってたな。)

 

7日目 Javaのパフォーマンスツールを覗いてみよう

A Sneak Peek at The Java Performance Toolbox - JVM Advent

  • jcmdみたいな標準のパフォーマンス解析ツールの紹介

 

8日目 Javadocコードスニペットとお友達

JavaDoc Code Snippets and Friends - JVM Advent

 

9日目 イベントに応じた処理の技術とメリット

The Art and Benefits of Computing Eventfully - JVM Advent

  • イベント駆動アーキテクチャの入門みたいな感じ。ちゃんと読んでみてもいいかも。

10日目 KotlinとKotestによるプロパティベースドテスト

Property-based testing with Kotlin and Kotest - JVM Advent

  • そのままの内容。個人的にプロパティベースドテストは探求したいテーマなので、ちゃんと読もうかな。

11日目 アクターと仮想スレッド。その組み合わせは天国か?

Actors and Virtual Threads, a match made in heaven? - JVM Advent

  • アクターモデルを仮想スレッドで実装してみたって感じ。面白そうなので読んでみようかな。

12日目 開発者としてのキャリアをシニアレベルを超えていくための6つのアクション

6 Actions to take Your Developer Career Beyond Senior Level - JVM Advent

  • 日本でも同じような議論があるなあ、という文化観察の意味で面白い。

13日目 GitHub のCIのYAMLファイルをどうやって、無くしたか

How I got rid of YAML in GitHub's CI - JVM Advent

  • kotlin DSLYAMLを生成する話

14日目 Elasticsearch 8x 最新で、最高!

Elasticsearch 8x latest and greatest - JVM Advent

  • Elasticsearchのアップデート情報。AWSと喧嘩してどうなっていくのかはちょっと興味深い。

15日目 クラウドネイティブ Javaの構成要素

Components of Cloud Native Java - JVM Advent

  • クラウドネイティブに必要なポイントとかコンテナとかCI/CD周りとか。若干今更感あるが、多くの技術者がそれに対応できてないって言ってるので、Java界隈は英語圏もそんなもんなのかなあ、という印象

16日目 2つの輪の力。開発生産性への別の視点

The Power of Two Rings - Another View onto Developer Productivity - JVM Advent

  • 開発者が行うinner loop(ローカルでコード書いて、テストしてってやつ)とプルリク後のレビュー/CI/CDでのouter loopの2つのフィードバックループがいいよって言ってるみたい。

17日目 Groovyとデータサイエンス

Groovy and Data Science - JVM Advent

  • pythonじゃなくて、Groovyでデータサイエンスライブラリ使うって話のよう
  •  

18日目 Kotlinで非同期/関数型Webサーバー

Asynchronous Functional Web Server in Kotlin - JVM Advent

  • Akkaやら仮想スレッド使ったWebAPIのパフォーマンス評価。仮想スレッドいいよ!って話みたい。

19日目 コミュニティのために、Javaをセキュアにしていく

Securing Java for the Community - JVM Advent

  • Eclipse Adoptiumのセキュリティ担保のプロセス。ありがとうございます。お世話になってます。

20日目 実業務で品質ピラミッドにどう取り組んでいくか。

How to Tackle the Pyramid of Quality in the Real World - JVM Advent

  • テストピラミッドのJavaでの実践編。いろんなブログとかでもあるけど、これもその一例として読めば良さそう。

21日目 Elasticsearchの内部

Elasticsearch Internals - JVM Advent

  • 読んで字の如し。読んでみる。luceneってライブラリがベースなんだと。

22日目 JVM ハローワールド

JVM Hello World - JVM Advent

23日目 JavaギークにとってのWebAssembly

WebAssembly for the Java Geek - JVM Advent

  • WebAssemblyの可能性について。単にブラウザ上の技術ではなく、プラットフォームになる可能性があるものだから、注視しようぜって言ってるみたい。個人的に「ブラウザの技術だから関係ないと思っちゃうかもだけど」って文脈で語られてて、あ、そういう感じなんだって思った。

24日目 PostgreSQLをメッセージキュートして使う

Using Postgres as a Message Queue - JVM Advent

  • 読んで字の如し。Spring Integrationで機能があるのでその紹介がメイン。個人的に今メッセージキュー的なものの選定しているので、候補になるかなあ、と思うなどしている。。。

25日目 ACRUMEN:一体全体ソフトウェア品質とはなんなんだ?

ACRUMEN: What is "software quality" anyway?! - JVM Advent

  • 品質特性の話。

 

まあ、レベル感としては日本と大差ないなあ、という感じ。

Temporal: 新しいワークフロー基盤を試してみようという話

Temporalとは

Uberで作られた信頼性の高いワークフロー/非同期実行基盤であるCadenceをforkして作られたもの。Cadenceを作った人たちがTemporal Technorogyというスタートアップを起業して作ったらしい。マネジメントサービスを提供してお金にしようとしているみたい。

なぜ試したいのか。

最初の動機は社内の昔ながらのジョブスケジューラ(日立のJP1/富士通のSystem Walker Operation Manager/IBM Tivoli/NTTデータのHinemos)から、もっとDev Opsとか開発者フレンドリーさであったり、クラウドとの親和性でったりしたものがないかと探していた。

ワークフローシステムとは

他の選択肢も色々検討してた。そもそもワークフローシステムと一口で言ってもかなり色んなユースケースだったり、ニュアンスの違いがある。自分が色々調べながら思ったのは以下のような分類。

システム運用/データ処理自動化

伝統的なジョブスケジューラは基本的には「システム運用」の自動化を目指したもので、インフラエンジニアとか運用エンジニア、今だとSREなんかが触るものとして設計されているように思われる。

Jenkins/Algo workflow/Apatche Airflow/Prefectなんかも結構その系統と思われる。

最近ではデータ分析が盛んになったので、プログラマーではないMLエンジニア、という新しいカテゴリも出てきたが、上記の比較的モダンなワークフローシステムはそういったニーズも意識して改善されているように思われる。

非エンジニア向けのローコードワークフロー

基本的にはアプリケーションの機能として提供されているもの。Saleforceであったり、oktaであったり、非エンジニアでも編集できるようになっている。

アプリケーションとしてのワークフロー

第3のカテゴリとしては、製品としてはActiviti/Camundaなどが該当する。よりプログラマーが扱うことを想定したワークフローシステム。

アプリケーションの中にワークフローが組み込まれるという形になる。多くの場合、そのアプリケーションはイベント駆動/非同期処理方式になり、その機能も備えている場合も多い。最近ではマイクロサービスを意識したSagaパターンの基盤として売り出そうとしているみたい。

ワークフローシステムの曖昧さ

ワークフローシステムは、結構面倒なのが、上記三つのカテゴリが意外とそれぞれが別のカテゴリの役割に担える傾向があること。伝統的なSIの開発では業務ロジックになる部分をジョブスケジューラのジョブネットで表現していた。結局ジョブスケジューラが無ければ、業務ロジックをテストできないってことになる。

プログラマー中心主義

自分のチームは基本は全員プログラマーで、どっちかというとプログラマーがインフラも見るって形になっている。当初はApatche AirflowやAlgo workflow(k8s使うので)を検討したのだけど、やはり、ワークフローを通常のコードと同じようなプロセスでテストやCIに乗せられるってこと、非同期処理なんかのニーズも増えていることもあり、3つ目のカテゴリであるActiviti/Camundaも試しに触って見てたりした。

そんな中、Java屋には有名なアメリカのソフトウェア開発コンサルティング会社Thoutworks のTechnorogy RaderにこのTemporalが紹介されていた。

Temporalのアーキテクチャと思想

システムアーキテクチャ

Temporalはワークフローを実行するworkerプロセスとそれを管理するサービス群(Temporal Cluster)の2種類に分けれれる。

https://docs.temporal.io/diagrams/temporal-platform-simple.svg

Temporal Clusterはgoで書かれており、workerは様々な言語で開発可能なSDKが提供されている。gRPCでworkerとClusterは接続され、登録されたワークフローの実行をworkerが行う。Clusterはworkerがワークフロー実行することをリトライなどを駆使して保証してくれる。

これは、CEOの人がAWS/Azure/Uberなんかでやってて、得た知見をもとにしているみたい。

ワークフローの書き方

ワークフローはそれぞれのSDKで普通にプログラミング言語で書く。Javaだとインタフェースを駆使してかく。ワークフローの内部でActivityを呼び出し、その結果などを判定してフローをコードで書いていく。普通のコードなので、普通にテストが書ける。

TemporalではActivityはリトライを繰り返し、実行されることを保証させ、ワークフローは一度だけ確実に成功するってのが典型的な設計。リトライしないように設計することもできるが、その場合も実行するときにworkerが落ちてた時などはworkerが復旧して接続されるまで待ってくれる。これをTemporalはDurable Executionと言っている。

Activityは決定論的に記述することが推奨される。まあ、何度やっても結果が同じってことで冪等性ってことなのかな、と思っている。DBインサートとかの場合には、一意のキーを使ってそれを実現しろ、って言ってますな。

良いと思った点。

  • 色んな言語でかける。ビジネスロジックJavaで、基盤的なところはgoで、とか。
  • プログラミングなので、なんかあってもどうにでもなる。
  • ビジネスロジックと切り離せるため、移行が容易
  • 信頼性の考え方がわかりやすい。

実は何より良かったのは、結構触ってみて、すぐ動かせたってこと。そして、複雑な要件を検討したところ、本当に色々考えられていて、かなり多くのユースケースに問題なく適用できそうってことを確認できた。

例えば、 - 長時間かかる大量ファイル処理 - ワークフローのアップデート/バージョンアップ - 監視/障害時調査と復旧 - 性能/データ量

チームのシニアエンジニアに見せても、パッと見て、「良さそう!」と印象を持ったとのこと。

加えて、slack見るとかなりちゃんとサポートしてくれているみたい。

実績

一応実績見ると、多分、CEOの人の人脈ありきだと思うけど、Netflix/ Datadog/ BOXみたいな誰もが知る優良企業でも使われているみたい。

Webアプリに適したものとそうでないもの

自分がここで書いたもの、WebAssemblyが広まっていくとちょっと変わっていくかもしれない。

----------

 

会社で自分が勧めて、neworkを使ってみてた。

nework.app

 

結構評判が良くてみんな使ってくれてたんだけど、slackにhuddleができて、neworkが有料化するタイミングもあって、huddleに移行しちゃった。

slack.com

 

neworkのコンセプトはとても良いし、個人的に、チームの外のひとが気軽に会話内容聞ける「聞き耳」機能は組織の風通しをよくする意味でとても良い、と思っていた。古い日本の会社でこれを作り出せるってのはとてもすごいと思う。継続して応援はしたい。

 

ただ、特にネットの状態が悪い時なんかは音質の劣化が激しい。出入りの際とか画面共有時にブツブツきれるみたいなものが解消されず、また、聞き耳機能みたいな物だったり、本当の雑談は一部の人しか活用できず、huddleと比較したら、有料Slackに追加でお金(手続きのコストも)を払ってまで導入するのはないな、という判断になってしまった。

 

個人的にWebアプリでやるべきものとそうでないものってあると思っている。RedmineみたいなのはWebと親和性高い。Webアプリとして使うもので、それが強みになるし、ホスティングサービスも有料でうまく行く。

 

一方でZoomがそうだけど、音声通話みたいなものってWebにしておくメリットってほぼないし、音声制御とかはネイティブアプリとかデスクトップアプリでガッチリ制御した方がいいと思う。huddleもweb版では利用できないっぽい。多分、技術的難しさがあるんだと思う。neworkは個人的にデザイン刷新なんか後回しにして、デスクトップアプリの開発に注力するべきだと思っている。

 

Webの思想と合わないってのはVS Codeもそう。JavaScriptとかは別かもだけど、Javaみたいな静的型付け言語を扱うのに、ブラウザベースのエディターってちょっと厳しい。あれが有料ならお金を払う人は少ないと思う。Intelij IDEAみたいにバリバリのデスクトップアプリにした方がいい。

 

同様に、業務システムなんかも基本、Webアプリとは相性が悪い場合が多いんじゃないかな、と。JetBrains Tool Boxみたいなアップデートを簡易にする方法を検討していくのがいい気がする。UXを求めるんならそこはコストのかけどころと感じる。「Quality is Free」なのだから。

 

 

 

 

APIテスト自動化ツールKarateをBDDツールとして使う

Karateとは

Karateは主にe2eテストを自動化するツール。cucumber的なfeatureファイルを書くとそれを実行できる。WebAPIのテストがその中心的ターゲット

github.com 

graalvmのjsライブラリで実現しているっぽいので、featureファイルからJavaも呼べる。

 

個人的にBDDというのが結構いいと思っていて、ビジネスルールの仕様なんかをビジネスサイドと意識合わせする場合に使えると思っている。アンクルボブはFitnesseというツールを作っている。

FrontPage

Fitnesseは名著『実践アジャイルテスト』でも紹介されていたもの

   

Fitnesseはアイデアはいいんだけど、wiki文書にテスト埋め込むとかまでしなくていいと思っていた。もっと簡便でメンテしやすい開発者フレンドリーなLiving Documentないかなあ、と。有名どころでは、Cucumberとかがあるんだけど、結局テストコードをドキュメントに合わせて2重に書くので、正直使いたくない。

Karateは簡潔なDSLAPI呼び出しの実行からアサーションまでをfeatureファイルに記述できる。かなり文書性が高く、テストコード特有の煩雑なノイズがない。普通に開発者が使うテストツールとしても使えると思う。

一つ思ったのが、ビジネスルール単体の仕様についてkarateで同様にかければユーザーとのコミュニケーションに便利なのではないか、と。 加えてSpring のBeanもテストしたいと思ってやってみた。

featureファイルはこんな感じ。

Feature: ビジネスロジックのテスト


  Background:
    * def CalcTestsRunner = Java.type('feature.calc.CalcFeatureTestsRunner')
    * table example
      | 入力値1 | 入力値2 | 期待結果 |
      | 10     | 20     | 30     |
      | 50     | 100    | 150    |
      | -10    | 10     | 0      |

  Scenario: シンプルなシナリオ
    * def x = 10
    * def result = CalcTestsRunner.testAdd(x,20)
    * assert result == 30

  Scenario Outline: データ駆動シナリオ データ例 <入力値1> + <入力値2> の結果は<期待結果>になる
    * def result = CalcTestsRunner.testAdd(<入力値1>,<入力値2>)
    * assert result == <期待結果>
    Examples:
      | example |
 

テストコードはこんな感じ

package feature.calc;

import com.example.demo.DemoApplication;
import com.example.demo.calc.CalcService;
import com.intuit.karate.junit5.Karate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(classes = DemoApplication.class)
public class CalcFeatureTestsRunner {

    static CalcService calcService;

    @Autowired
    public  void setCalcService(CalcService calcService) {
        CalcFeatureTestsRunner.calcService = calcService;
    }

    @Karate.Test
    Karate testCalc() {
        return Karate.run("calc").relativeTo(getClass());
    }

    public static int testAdd(int input1,int input2){
        //仕様を実現するコードを書いていく。流動的で良い
        return calcService.add(input1,input2);
    }

}

featureファイルにはプロダクションコードのクラスを直接書かない。リファクタリングするとき面倒になるから。 こんな感じで実行できる。

f:id:masatsugumatsus:20210319144510p:plain

レポートはこんな感じ

f:id:masatsugumatsus:20210319144755p:plain

githubにアップしました。

github.com

イメージ/観念と思考/行動

イメージ/観念にもとづいて人は認知し、思考/行動する。また、認知→思考/行動というのは、意識する前に開始されていることも多い。
 
その意味で、自分たちがもっているイメージ/観念というのは意識できるものもあれば、無意識にしか存在しないものもある。どちらも我々の思考と行動の基盤となっている。
 
思考と行動を変化させようと思ったら、様々なtryをして、自分が実際に持っているイメージや観念を探求する必要がある。
 
色んな事に頑張ってチャレンジすることも有用だが、最近はそれよりも日常の活動や小さな思考、行動の気づきを深めていくことの方が実りが多きく、楽で、早い、と思うようになった。
 
最近、やっているのは、右と左の観念を廃して、景色をみる、ということ。空間全体を把握しようとしだすから、もしかしたら、生来のものと思っていた方向音痴を直せるかもしれない。
 
また、他者からのフィードバックや他者との比較も有用。自尊心を脇に置いて、自分と違う結果にどのように至っているのか、というシステムを探求する。

ワインバーグの成長のプロセスモデル

スキルの熟達についてのワインバーグのモデル

元ネタ

 

 

  • 成長はきれいな直線を描かない。
  • あるレベルまで成長すると踊り場に到達する。その時、新しいやり方を試すことで飛躍する。
  • 新しいやり方に習熟するまではパフォーマンスは落ちる。

 

 

f:id:masatsugumatsus:20210228215008p:plain

 

 

要求定義の双子プロセスについて

 
 
要求の作成は、アジャイルだろうと、ウォーターフォールプロセス的なシーケンシャルアプローチだろうと必要だ。要求開発をソフトウェア開発と並列して進行する別のプロセスとして管理することを提案している。
ワインバーグは、どのような製品であったり、組織として採用しているプロセスがどうあれ、
  • 製品の使用者からのフィードバック
  • 開発者からのフィードバック
  • ビジネス目標の変化
などが恒常的に発生しているという観察した。
 
そのため、プロダクト開発のプロセスとは「別」に要求開発のプロセスも管理しようというのがワインバーグの双子プロセスの提案である。(正確にはParnasとClementsの記事に基づく。下記の図は『ワインバーグのシステム変革法』 図15-5からの図を少し改変したもの。)



たとえば、Scrumなどでは要求はPOが定義し、開発者に提示することになっているが、開発者に説明できる要求をPOが手にするまでには複雑なプロセスが必要だ。それには、多くの場合、政治的な交渉も含まれる。
 
 
要求開発プロセスを別のプロセスとして定義することは、ブラックボックスとなっていいるプロセスを明確なものにし、政治力などによって左右されるのではなく、要求開発のプロセス改善を可能にする、という意味がある。政治力というのは、ビジネスサイドのことばかりではなく、自分の判断で要求を取り込む開発者もある面では政治力がある。ようは、ソフトウェア開発プロセスに対する影響力を持つ人が要件を決めてしまうということになる。
 
 
詳細な要求開発のプロセスは例えば、次のようなものだ。(『ワインバーグのシステム変革法』 図16-5からの図を少し改変したもの。)
 

 
要求開発には開発者もステークホルダーとして参画する。主に開発することで得た知見をもとにした要求アイデアの提示、一部の開発者は要求定義のレビューにも参画する必要があるだろう。シーケンシャルプロセスで同一リリースに要求が追加されるのなら、変更管理となる。
 
アジャイルプロセスにおいては分類、高次設計、優先度設計などはソフトウェア開発プロセスに含めてもいいだろう。Scrumなどのソフトウェア開発プロセスの中で仕様化するプロダクトバックログリファインメントで行うから。
 
要求開発のプロセスそのものを管理し、様々な情報を基に最終的な意思決定を行うのは、ワインバーグはマネージャーだといっている。おそらく、プロダクトの真のオーナーであるプロダクトマネージャーだと思う。彼らはプロダクトに対する最終的な意思決定を行い、おそらく、その結果とプロセスについて、ステークホルダーに対して説明責任を持つ。日本の組織の場合はこのロールが不在のため、うまくいかないことが多いように思う。
 
現在では、どういうプロセスモデルでソフトウェアを開発するにせよ、プロジェクトが継続的に立ち上がるってことは避けられないように思う。こうした要求開発プロセスを切り出すことができ、そしてプロセス改善を行うことがおそらく、アジャイル開発にするか、、柔軟なウォーターフォールにするか、という選択よりも意味のあるものなのではないかと感じている。